#clojure log - Nov 27 2013

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

0:01 amalloy: justin_smith: i can't tell which of his proposed forms you're saying you prefer

0:02 justin_smith: I'm saying the latter is better, and that maybe it doesn't need to be a macro (it is so close to being a normal let with some symbols scrambled)

0:02 bellkev: That's a fair point... I guess my thinking was just that since a "template" is such a key entity in the world of AWS, it would be nice if there was a 1:1 mapping between clojure-based template file with a single root element (like project.clj) and AWS JSON-based CloudFormation template

0:03 justin_smith: and I guess that would be my "replicating something in the domain that makes it clearer"

0:04 I don't know the thing you are translating to, so the value of that could have been lost to me

0:05 bellkev: Yeah... It's still definitely a judgement call...

0:05 The context though is that, basically these templates are huge JSON files that a lot of people hand edit

0:06 justin_smith: what about a toolkit that breaks down the json file into clojure maps, provides some convenience functions for manipulating and recombining them, and then turns the maps back into json?

0:06 bellkev: And AWS makes tools, like an Eclipse plugin (shudder) that make it easier to write them, with code completion, etc, but it's still just hand-edited JSON

0:07 That's a possibility

0:07 justin_smith: that way we get clojure's extensive data manipulation power

0:08 that is what I would hope to find if I had to deal with this format

0:08 bellkev: Another thing I want to do is allow custom resource types, some deftypes/defprotocols for resources, which would definitely involve multiple external entities in addition to just the templates

0:08 justin_smith: the json -> clojure should be very easy (cheshire or data.json), the hard part probably bein enforcing whatever properties cloudfront expects when you go from clojure data back to json again

0:09 why do you want deftypes?

0:09 do they make something easier?

0:09 bellkev: Also, there are API calls launch these templates, so there are a lot of cool use cases you could come up with to combine my idea with amazonica or just the AWS Java API to launch stacks

0:10 You can make custom resources, which have to implement create/update/delete methods, so I thought that might be a reasonable thing to have a protocol for

0:11 Yeah, I already played with the conversion to/from JSON, and it's no sweat

0:11 justin_smith: I had to use a protocol today because I wanted people to be able to use zookeeper to coordinate caribou.core instances, but did not want zookeeper to be a prerequisite to using caribou.core

0:11 bellkev: They also publish a JSON schema, which enables programmatic validation

0:11 justin_smith: if all you need is to ensure certain functions are implemented, why not a function that takes three functions as args?

0:12 bellkev: Oh yeah, I saw the Caribou announcement BTW, congrats!

0:12 justin_smith: thanks

0:13 what I am saying is that stuff like protocols and types are helpful if you need to make optional implementations more modular, or you need a speed boost, but they can just encumber things if they are not needed

0:13 s/types/deftypes

0:14 bellkev: sorry, what do you mean "s/types/deftypes"?

0:14 justin_smith: I said something about types above, and more precisely meant usage of deftype

0:15 or defrecord (which is probably closer to what you want if you wanted either)

0:15 bellkev: So, Caribou is like Spring for Clojure?

0:15 Does it do cool stuff with xml? :P

0:15 justin_smith: umm, should I be insulted?

0:16 it's a map view controller framework - we translate clojure maps into sql records and back again

0:16 bellkev: haha, I'm just kidding, I haven't even really looked at it

0:16 Oh, that sounds cool

0:17 So it's like a Clojure ORM?

0:17 j/k

0:17 justin_smith: not arbitrary maps, but we try to keep things as simple and vanilla clojure as possible

0:17 omm

0:17 errr

0:17 mrm

0:17 map relational model :)

0:17 bellkev: I was just checking out ClojureQL today, and wondering if there was something like that

0:18 justin_smith: caribou uses sql because that is a well understood way to persist structured data describing content (slideshow -> slides -> captions that kind of thing)

0:19 it isn't meant as a way to use sql

0:19 it uses sql because it happened to be handy for the job we wanted to do

0:25 yedi: so a while back i somehow got nrepl set up in emacs, i wanna start using cider now and am looking into some emacs bundles. anyone have experience with https://github.com/overtone/emacs-live ?

0:25 or emacs-prelude

0:25 clojurebot: I don't understand.

0:25 bellkev: amalloy: I was just going to ask you for more info about the "anaphoric" macro examples, but I just found your blog post about it ;)

0:26 I'll check it out!

0:26 yedi: is there a general suggestion you have for newcomers looking to get set up on emacs?

0:26 justin_smith: if you start with one of those quick-starts, I wouldn't look to switch to a new one, I would look to customize it to your needs

0:27 but then again I started with emacs totally vanilla, and only got into the good stuff slowly

0:28 I think many learners get overwhelmed with all the gee-whiz and optional awesomeness, where it is more useful if you learn the core movement / cutting / yanking / auto-documentation stuff first

0:28 that's just my opinion though

0:29 yedi: yea i have been using emacs for clojure dev recently and am familiar with the controls, my concern is that i'm using emacs to its fullest potential for interactive clojure dev

0:30 justin_smith: I have heard conflicting reports about whether cider is really ready

0:30 if you have nrepl and paredit, you should be good

0:32 `cbp: emacs-live is cool if you're only doing clojure but it doesnt use cider

0:34 devn: meh to emacs-live

0:35 yedi: `cbp: yea that's what emacs-live's repo seems to say

0:35 devn: not trying to be a jerk or anything, but i find the amount of opinions to be rather annoying

0:35 yedi: https://github.com/clojure-emacs/cider#emacs-live is lyin

0:36 devn: like fn becoming the lambda, rainbow parens, the nrepl settings, indentation settings, etc.

0:36 the structure to the whole thing is a big rat's nest too IMO

0:36 there are these nested modules which have special user configs, yadda yadda -- layers of indirection

0:37 it feels like java + elisp

0:37 </rant>

0:37 that being said, i really appreciate some of the cosmetic touches they've added, it's just too much for me personally

0:38 technomancy: yedi: the most popular one is the emacs starter kit

0:38 which is deprecated because the whole idea is flawed at its root

0:38 https://github.com/technomancy/emacs-starter-kit/blob/v3/README.markdown

0:38 devn: technomancy: i liked the starter kit when it wasn't modular

0:39 :X

0:39 technomancy: devn: it was a necessary evil

0:39 since at the time no one used package.el

0:39 clojurebot: Cool story bro.

0:39 technomancy: these days everything is a package; just pull in the stuff you want and leave out what you don't

0:40 yedi: i guess i'm just worried i'm missing out on useful emacs functionality for devving clojure

0:40 justin_smith: https://github.com/technomancy/better-defaults the better-defaults are close to what I eneded up at naturally after years of use

0:41 for optional packages, use package mode, try them out, uninstall them if you don't like them

0:41 technomancy: yedi: you can find useful emacs functionality more easily by exploring packages than adopting a big pile of preselected junk all together

0:41 justin_smith: exactly

0:41 technomancy: that said, better-defaults is not a bad place to start

0:41 justin_smith: looks like it is all stuff that comes with vanilla emacs, just a better config for them

0:42 yedi: sweet thanks guys

0:43 justin_smith: my most recent upgrade was simple shortcuts for hs-hide-block and hs-show-block

0:43 makes reading source files much easier

0:45 technomancy: wtf; the cider google group isn't visible to non-members

0:45 justin_smith: out-ciders are not welcome

0:46 technomancy: >_<

0:46 https://github.com/clojure-emacs/cider/issues/424

0:47 * technomancy tries to remember if he's ever gotten a reply from someone who wasn't cemerick on the clojure-tools mailing list

0:48 cemerick: technomancy: funny, just pinned the latest for a reply tomorrow or friday :-P

0:48 clojurebot: It's greek to me.

0:48 cemerick: This is what happens when I create google groups

0:49 yedi: justin_smith: ahhhh that was too good xD

0:50 technomancy: cemerick: I might end up cross-posting

0:50 to the main one

0:50 or maybe I'll wait till I have a POC

0:51 yedi: so how would I actually go about getting better-defaults.el on emacs? i'm assuming i add some code to the .emacs.d/init.el file?

0:51 justin_smith: I'm out, night all

0:51 technomancy: yedi: M-x package-install better-defaults

0:51 yedi: oh what so easy

0:51 technomancy: justin_smith: me too

0:51 cemerick: technomancy: I think it's safe to say that anyone who hasn't thought about that particular topic before probably isn't equipped to dive in and grok the constraints in any period of time you'll be willing to wait.

0:51 Or maybe I'm just being a cynical ass.

0:52 technomancy: cemerick: I am a bit impatient when it comes to sweet tooling hacks

0:52 I would like to make it easier for regular clojure hackers who've never touched elisp to enhance their environment though

0:53 yedi: technomancy: it says it can't be found, is there somewhere package library i need to import or something?

0:53 cemerick: technomancy: as long as you keep other environments in mind, just spike it. Target something other than emacs to prove the "portability" of the approach, and you'll be ~good.

0:54 technomancy: yedi: yeah, if you don't already have marmalade on your package list it won't work

0:54 see http://marmalade-repo.org

0:54 cemerick: "target something other than emacs" I'm not gonna learn vimscript chas =P

0:54 cemerick: heh

0:55 technomancy: cemerick: what do you think about HTML responses that have local hyperlinks?

0:55 it's easy to redirect those to nrepl messages in emacs

0:55 cemerick: technomancy: hey look, if I can write Eclipse plugins, vim plugins, _and_ submit PRs to clojure-mode… :-P

0:55 technomancy: hehe

0:55 but I have no idea if that's possible with other HTML renderers

0:55 bitemyapp: cemerick: vim is sie enemy.

0:56 technomancy: it would really be a bummer not have that capability portably

0:56 bitemyapp: technomancy: what capability?

0:57 cemerick: technomancy: this would be accomplished by having the local tool hang click handlers on buttons in webkit, etc?

0:57 technomancy: bitemyapp: the ability for an nrepl handler to return HTML containing hyperlinks that point to other nrepl endpoints

0:57 cemerick: aye

0:57 bitemyapp: useful for porting the slime inspector (for instance) to nrepl

0:57 cemerick: technomancy: if an environment can embed webkit, that's a pretty reasonable piece of functionality to assume

0:57 bitemyapp: yeah...that's a good idea.

0:58 technomancy: cemerick: right; the question is whether the webkit stuff can be bidirectional

0:58 bitemyapp: wait why does this functionality need webkit?

0:58 what's going on QQ

0:58 technomancy: gonna just assume it's possible

0:58 bitemyapp: webkit is just how it would probably happen for CCW

0:58 cemerick: technomancy: as in, delivering incremental updates for a particular view

0:58 technomancy: cemerick: right, without going over HTTP

0:58 bitemyapp: technomancy: just to have clickable links to nrepl stuff? wut

0:59 technomancy: bitemyapp: webkit to have rich rendering in general

0:59 intra-nrepl links is just the icing

1:00 bitemyapp: technomancy: can we just have a working stepping debugger first?

1:00 technomancy: bitemyapp: I'm just laying the groundwork; you can build on it

1:00 bitemyapp: we have every toy except the one every ghetto language on the planet has.

1:00 cemerick: bitemyapp: I think "patches welcome" is the general party line.

1:00 technomancy: I want to make drracket stuff possible

1:00 bitemyapp: until I found out about schmettertoomanyfuckingletters I thought it was a lost cause after seeing Ritz.

1:01 Ritz made me lose all hope in a usable debugger. Seriously.

1:01 technomancy: bitemyapp: http://p.hagelb.org/make-it-sew.gif

1:01 bitemyapp: so, next step is to make schmetterwhateverthefuck abstracted into just an HTML frontend for an nrepl provider?

1:02 technomancy: if you want hyperlinks, I guess?

1:02 bitemyapp: that's...what no.

1:02 coventry: schmetterling is so easy to read, compared to ritz.

1:02 bitemyapp: `cbp: still looking for a project or is Haskell keeping you occupied?

1:02 k, I'm calling it zergling.

1:02 k? k.

1:02 zRecursive: ,(doc ->>)

1:02 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

1:03 cemerick: bitemyapp: HTML is just the start. Hoping to abstract over canvas for proper visualization of data structures and such. It shouldn't be a very large change to the nREPL protocol.

1:03 bitemyapp: ~zergling is https://github.com/prismofeverything/schmetterling

1:03 clojurebot: You don't have to tell me twice.

1:03 bitemyapp: actually sometimes I do.

1:04 * technomancy heads off like he said he wa sgonna

1:04 hiredman: ugh

1:04 yuck

1:04 `cbp: bitemyapp: always up for ideas. Atm im starting the heckle thing + apparently rdb got an update so i gotta sync up revise with that

1:04 hiredman: sending data over the is better than sending a rendering of the data

1:05 bitemyapp: `cbp: cool. Those sound like great ideas.

1:05 `cbp: I saw the RethinkDB update, couldn't tell what, if any, parts of the protocol changed.

1:05 I bumped Revise in the Hacker News thread.

1:05 hiredman: #chart/rows [[1 2] [3 4] [5 6]] over a blob of canvas anyday

1:05 `cbp: bitemyapp: :D

1:05 bitemyapp: did you have another project?

1:06 bitemyapp: `cbp: not a terribly serious one, but zergling could be abstracted into a generic nrepl thing so that Clojure would have a decent debugger.

1:06 then you'd make nrepl frontends for the debugger in Emacs, vi, etc etc

1:07 well, not *you* you, you know what I mean.

1:07 `cbp: oh

1:08 that looks cool

1:08 bitemyapp: the nrepl protocol has been on my brain lately.

1:14 SegFaultAX: Heh, vi.

1:14 bitemyapp: Heh indeed.

1:15 SegFaultAX: I haven't used actual vi in like 5+ years.

1:20 Apage43: I probably last used it 4 or so years ago

1:20 when I had to touch HP-UX and AIX A lot

1:20 bitemyapp: Apage43: do you seek out mental agony in your career on purpose?

1:21 Apage43: I stumble into it, and never figured out how to stumble out

1:21 SegFaultAX: I haven't used a distro in 5+ years that didn't make vi a symlink to vim with set compat.

1:22 bitemyapp: Apage43: You live in the bay area, just work at one of those companies with with an xbox in the office. Suddenly the tech becomes easy mode but you're surrounded by people that might be a little soft-headed.

1:22 Apage43: these boxes ran ksh '88

1:22 bitemyapp: SegFaultAX: does anybody use vim without compat?

1:22 sadists?

1:22 Apage43: I was using software that hadn't been updated *in my lifetime*

1:22 bitemyapp: masochists*

1:22 `cbp: i used it this morning ;-;

1:22 SegFaultAX: bitemyapp: Dudewut? No one sets compat

1:22 Apage43: bitemyapp: we have an xbox. and a kegerator.

1:23 noone has ever turned on the xbox

1:23 also I have to write C89 sometimes

1:23 SegFaultAX: Apage43: To be clear, I've been a vim user for most of my Linuxing life. I was merely noting how uncommon actual vi is.

1:24 bitemyapp: Apage43: right, so you're surrounded by soft-headed people that like Golang. But I repeat myself.

1:24 I find C apologists really funny, it's like they don't actually know many death-traps there are without upgrading to C++.

1:24 Apage43: I wonder if I could argue that it also falls into that "doesn't include any advancements that have been made in my lifetime" category

1:25 bitemyapp: just wade into ##C for a week, look at the raw paranoia and fear surrounding the massive swath of territory that constitutes "undefined" behavior in the standard.

1:25 Apage43: SegFaultAX: Me too.

1:25 I mean, to find actual vi I had to actually not be on a linux machine

1:25 bitemyapp: most of the "undefined" behavior in Clojure people bump into is "is hash-map guaranteeing an order?"

1:25 yedi: omg cljs are so sex

1:26 bitemyapp: yedi: are you okay?

1:26 yedi: well here, have more sex.

1:26 ~zergling

1:26 clojurebot: zergling is https://github.com/prismofeverything/schmetterling

1:26 Apage43: i saw that today

1:26 i had an accident

1:27 bitemyapp: +1 please https://github.com/prismofeverything/schmetterling/issues/3

1:28 yedi: that is amazing

1:29 `cbp: github has no voting :(

1:29 bitemyapp: `cbp: there are emoticons, just +1 in a comment.

3:03 wink: hehe, awesome

3:04 possibly related: http://www.youtube.com/watch?v=ZlATOHGj9EY (no flash, but should be correct vid)

3:32 wei__: what's a good way to get java.jdbc to put a biginteger type into a Postgres BIGINT field?

3:42 yedi: hmmm... should i store this state within a closure or using an atom

3:54 amalloy: yedi: storing it in an atom that's *not* in a closure sounds like a mistake. making it global is such a commitment

4:53 sm0ke: when i run 'lein repl' outside a project how do i find out the port for nrepl server?

4:55 lumafi: it says something like this when it starts: nREPL server started on port 55636 on host

5:23 rurumate: is there a variant of (if) that returns identity by default, instead of nil?

5:24 nightfly: or?

5:24 rurumate: hm

5:24 yes that would be possible

5:25 but then you have to nest your condition in an and, making it a bit harder to read

5:25 clgv: you mean instead of (if x y x)?

5:25 rurumate: yes

5:25 because the x at the end looks a bit ugly

5:26 and is easily overlooked when y gets big

5:27 more like (if (test x) y x)

5:27 ohcibi: ok, I have this NxM matrix which I want to partition into all columns into 4-tuples, I do this with (map #(partition 4 1 %) myMatrix), which yields something like (a1, a2, a3, a4), (a2, a3, a4, a5).... I now need not only the values but also the coordinates of each value.. e.g. (([0 0] a1), ([0 1] a2),....). i like my partition solution but I think I need to generate all coordinates and then (get-in) from myMatrix, or does anyone know a cool trick how to do this

5:27 at once?

5:28 rurumate: ohcibi: lisp may not be the ideal language for vector manipulation

5:29 ohcibi: rurumate: so you also think (get-in) is the way to go?

5:30 rurumate: there is map-indexed, not sure if it helps

5:31 ohcibi: rurumate: hm,, i'll see but i guess this is only good for one coordinate...

6:04 clgv: ohcibi: there is core.matrix for vectors and matrices

6:15 zeebrah: is there a defn* macro available somewhere which allows nested defn*s?

6:16 clgv: zeebrah: you can use (letfn [(f [x] ...)] ...) therefore

6:16 zeebrah: the defn* you describe makes no sense in clojure

6:16 zeebrah: clgv: avoiding lets, they're obscuring

6:17 llasram: lol

6:17 zeebrah: whyh doesn't it make sense?

6:17 clgv: zeebrah: since every `def` operates on namespace level and thus is always globally accessible

6:18 zeebrah: avoiding `let` won't work if you ever want to write proper Clojure

6:30 zeebrah: clgv: defn*s inside would expand to a (let [... tho

6:31 clgv: zeebrah: then they are wrongly named.

6:31 zeebrah: and for that task just use (letfn [(f [x] ...)] ...)

6:33 zeebrah: like i said it looks ugly :P

6:34 what i am after is a define like scheme's for working through sicp because I can't bring myself to use scheme and apparently clojure is not quite right

6:34 llasram: zeebrah: Without mutation, you need to create some sort of new lexical scope for each binding

6:34 `def` doesn't create a scope because it actually does work through mutation

6:35 In order for your `def*` to somehow expand to `let`, it would need to have the forms where the binding is visible be *inside* the `def*`

6:35 e.g., just be a `let`

6:35 er, i.e.

6:35 clgv: llasram: good explanation, zeebrah: following the explanation you'll end with something "let-like" ;)

6:36 zeebrah: i'll have to think about it, i don't understand right away

6:36 llasram: While you're doing that, try using `let` :-)

6:37 I thought it would be awkward at first, and is something other people I've introduced to Clojure have complained about at first

6:37 But the benefits of an obvious lexical scope for each binding quickly outweigh any initial awkwardness

6:58 magopian: hello

6:59 llasram: salutations

7:00 magopian: can't remember how to have a bot here run clojure, can somebody tell me?

7:00 amalloy: i mean, scheme's internal define isn't the worst thing ever

7:00 ,1

7:00 clojurebot: 1

7:00 magopian: thanks amalloy

7:00 llasram: amalloy: ALL MUST PERISH BEFORE THE MIGHT OF `let`

7:01 magopian: ,(for [row [:top :middle] column [:left :middle]] (vec row column))

7:01 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$vec>

7:01 magopian: ,(for [row [:top :middle] column [:left :middle]] (vector row column))

7:01 clojurebot: ([:top :left] [:top :middle] [:middle :left] [:middle :middle])

7:01 llasram: amalloy: Aren't you PST? Clojure all night long?

7:01 amalloy: it would be a fun little exercise to write a define macro that acts like scheme's

7:01 magopian: ,(for [row [:top :middle] column [:left :middle]] [row column])

7:01 clojurebot: ([:top :left] [:top :middle] [:middle :left] [:middle :middle])

7:01 amalloy: llasram: well, i drift pretty far towards nocturnal when i don't have a job :P

7:02 llasram: amalloy: Ah, I see. To the night!

7:02 magopian: ,(= (1 2) [1 2])

7:02 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

7:02 magopian: ,(= '(1 2) [1 2])

7:02 clojurebot: true

7:02 llasram: amalloy: Where would you keep the current environment though?

7:02 amalloy: magopian: if you're just using clojurebot as your repl, please private-message him

7:02 magopian: oh, sure, truly sorry about that :/

7:03 amalloy: llasram: what environment? you just have the macro transform (define (a x) (define (b y) y) (b x)) into (defn a [x] (letfn [(b [y] y)] (b x)))

7:04 magopian: amalloy: how should I tell clojurebot to display the full result, instead of "ellipsing" it?

7:04 amalloy: and just in like scheme, you require that all "internal define"s come first in the function body

7:04 magopian: ask lazybot instead

7:04 &(range 40)

7:04 lazybot: ⇒ (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39)

7:04 amalloy: &(range 400)

7:04 lazybot: ⇒ (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 ... https://www.refheap.com/21283

7:04 magopian: ah, i then use the other one, thanks amalloy ;)

7:05 llasram: amalloy: Ah, of course. I was trying to puzzle around having a top-level form containing all the `define`s, but you really can't do without it

7:05 amalloy: what do you mean, top-level?

7:06 llasram: Containing all the `define`s

7:06 amalloy: uhhhhh, are you talking about something like (with-scheme-stuff (define ...))? i think you can do it without that wrapping macro

7:07 magopian: mmm, I'm working through the clojurescript koans, and I'm stuck on http://clojurescriptkoans.com/#sequence-comprehensions/5 with what I believe is the correct answer (which is to type in "[row column]" without the quotes)

7:07 llasram: You need *something*, like a `defn` replacement

7:07 amalloy: llasram: right. define is that defn replacement

7:07 llasram: Right :-)

7:07 magopian: and it seems lazybot is also ok with that, however, i'm being tolk Ii have not yet attained enlightenments.

7:07 llasram: I was missing that part, which makes it a bit more elegant

7:07 magopian: s/tolk/told

7:08 amalloy: magopian: works for me. maybe you typed it wrong?

7:09 magopian: amalloy: i tried several times... strange, i'll try to clear the cache or something

7:10 nope, no better... it's just [row column], right?

7:10 amalloy: yep. i just copy/pasted that from you, hit enter, and it moved on

7:11 magopian: mpf

7:12 llasram: amalloy: If it's not impolite to ask, what's the next project?

7:19 magopian: amalloy: actually, it works if I use chromium, but not firefox, this is so strange... what browser did you use for your test?

7:23 amalloy: chrome

7:24 magopian: amalloy: might be some issue with Firefox, I created an issue on github, thanks for the feedback amalloy

7:27 amalloy: llasram: dunno yet. taking a little time to relax, looking at opportunities

7:30 llasram: That seems like the right way to do it

7:33 dabd: what is the most idiomatic way to use a var from a namespace? (:require [some-ns :refer [some-var]]) or instead (:use [some-ns :only [some-var]])

7:33 llasram: dabd: the former, although

7:33 dabd: ok the style guide adivses using :require :refer :all instead of :use in the ns macro

7:33 llasram: I'd argue more for (:require [some.ns :as some]) then some/var

7:34 Which style guide?

7:34 dabd: https://github.com/bbatsov/clojure-style-guide

7:34 llasram: Oh, that one

7:35 dabd: what is the difference between using each form in my first question?

7:35 amalloy: it really should recommend using neither of those

7:35 llasram: I mean, I'd agree with it in this case, although I'd also argue that :refer :all is rarely the right thing to do either

7:35 dabd: amalloy: how should i use a single var from a ns then?

7:36 llasram: I keep meaning to for that thing... I disagree without maybe 30% of it, but AFAICT nobody else has bothered to codify style

7:36 amalloy: dabd: nono, :refer foo is fine

7:36 llasram: s,for that,fork that,

7:36 amalloy: but :refer :all is bad

7:36 dabd: what about this document? http://dev.clojure.org/display/community/Library+Coding+Standards

7:36 should be more "official"

7:36 a lot of the first document was taken from here anyway

7:37 llasram: They're largely at different levels though

7:47 sveri: anybody compared pedestal to luminus here?

7:58 wink: I heard some criticism of https://github.com/bbatsov/clojure-style-guide but can't remember which

7:59 let's rephrase it to: it seems to be controversial for a less silly statement

8:17 dabd: the style guide also advises: Use seq as a terminating condition to test whether a sequence is empty (this technique is sometimes called nil punning). So should we use (seq s) instead of (empty? s)?

8:17 I meant (not (empty? s)

8:21 TEttinger: dabd, yes

8:21 (doc empty?)

8:21 clojurebot: "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

8:22 dabd: I wonder why this idiom is used when we are interested in the boolean value

8:24 clgv: dabd: in bottlenecks of your application I'd avoid seq

8:26 dabd: I don't understand why should i construct a seq if I want to test if it is empty

8:26 (doc seq)

8:26 clojurebot: "([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable."

8:31 CookedGryphon: dabd: presumably though it's just trying to get an iterator and giving nil if it can't

8:31 it's not like it's doing anything heavyweight to construct the seq

9:12 allsystemsarego: n00b question: what's the simplest way to add core.logic to the classpath so I can start experimenting with it with minimal fuss?

9:13 clgv: allsystemsarego: create a leiningen project and add core.logic to the dependencies

9:13 hyPiRion: ^

9:13 allsystemsarego: ok, thanks

9:13 clgv: allsystemsarego: there is also the leiningen plugin lein-try but for the first setup it is not easier - you only benefit from it if you want to try libs without projects more than once ;)

9:15 allsystemsarego: ok, and afterwards do I need to use clj or lein repl as the interactive console?

9:15 justin_smith: ,(subs "😸😾" 0 2)

9:15 clojurebot: "??"

9:15 justin_smith: (failed test from http://mortoray.com/2013/11/27/the-string-type-is-broken/)

9:17 xsyn: Please can someone help me

9:17 I think I'm using map incorrectly

9:17 justin_smith: xsyn: let me guess: you are mapping but the function you call in the map is not getting called?

9:17 and you are not using the output of the map call anywhere?

9:18 xsyn: just setting up a gist

9:18 justin_smith: the map errors and says it can't cast a long to an iseq

9:19 https://gist.github.com/anonymous/7676445

9:19 justin_smith: not the usual error then

9:19 yeah, every arg to map after the second must be a sequence

9:19 (inc depth) is not a sequence

9:20 xsyn: a

9:20 ah!

9:20 is there a better way to iterate that?

9:20 justin_smith: is (inc depth) meant to be an argument to map?

9:20 xsyn: no, to the function

9:21 so that's where I'm confused

9:21 the function takes two arguements

9:21 the coll, and then (inc depth)

9:21 justin_smith: then use an anonymous function, or swap the arg order and use partial

9:22 xsyn: ah, thanks for the help

9:22 justin_smith: (map #(followers-followers % (inc depth)) (get-folower-ids id))

9:22 xsyn: Man, I almost got there

9:22 justin_smith: map works on multiple sequences

9:22 xsyn: thanks

9:22 justin_smith: another option: (map + (range 10) (constantly 2))

9:23 you can use constantly to get a single value an indefinite number of times in a collection

9:23 ,(map + (range 10) (constantly 2))

9:23 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly$fn__4051>

9:23 justin_smith: err

9:23 ,(map + (range 10) (repeatedly 2))

9:23 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

9:23 justin_smith: ,(map + (range 10) (repeat 2))

9:23 clojurebot: (2 3 4 5 6 ...)

9:23 justin_smith: finally!

9:23 I should really get those straight

9:28 xsyn: it doesn't work quite like expected, but you answered my question thanks

9:29 clgv: ,[(repeat 10 (rand-int)) (repeatedly 10 rand-int)]

9:29 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$rand-int>

9:29 justin_smith: rand would work

9:29 clgv: ,[(repeat 10 (rand-int 20)) (repeatedly 10 #(rand-int 20))]

9:29 clojurebot: [(15 15 15 15 15 ...) (12 8 18 5 14 ...)]

9:30 justin_smith: or that

9:30 for some reason I get constantly / repeat / repeatedly conflated - I should use them all more so I can keep them straight

9:36 gfredericks: I have 2 core.async questions

9:36 A) Can a producer detect that a channel is closed?

9:37 B) What's the best mechanism for detecting that a not-message-dropping channel is full?

9:41 dsrx: ,(doc repeatedly)

9:41 clojurebot: "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

9:41 justin_smith: https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj the examples seem to suggest using thread for the latter situation (so the thread can block, but your other code does not)

9:42 halogenandtoast: Is there a cleaner way to do (get-in json ["data" "children" 0 "data" "title"])

9:42 dsrx: oh i misread 'with side effects' as 'without side effects' and was totally confused

9:43 justin_smith: gfredericks: never mind what I just said

9:57 xsyn: justin_smith: NOW I'm having that problem, where map isn't producing expected output

9:57 returns a (nil nil)

9:57 and the a prntln in the function doesn't get called

9:57 justin_smith: can you paste the latest?

9:59 xsyn: https://gist.github.com/anonymous/7677135

10:00 justin_smith: small tip: (vector (map ...)) can be replaced by mapv

10:01 also, it looks like the depth and id args may be getting used out of order?

10:02 you are passing in (inc depth) in the position that is called id

10:03 looks like I got the order wrong when I was trying to show you how to do it ealier

10:03 *earlier

10:06 xsyn: no no, that was me

10:07 hah, that's awesome

10:09 justin_smith: so you got it working?

10:14 moquist: I'm trying to figure out how to (require ...) libs in a clojurescript browser-REPL. For some reason, I'm just not getting it right. I've tried googling around a bit, and I find instructions for requiring libs in a .cljs file, but not in a bREPL.

10:15 Can somebody point me in the right direction?

10:16 xsyn: justin_smith: Yeah, thank you

10:22 halogenandtoast: Would something like this be frowned upon: (map #(-> % :data :title) (-> json :data :children)))

10:23 justin_smith: looks cromulant to me, though you could use get-in instead of ->

10:23 pjstadig: or (comp :title :data)

10:23 `cbp: ~cromulant

10:23 clojurebot: Gabh mo leithscéal?

10:23 justin_smith: pjstadig: that is how I would usually do it, yeah

10:24 `cbp: http://en.wiktionary.org/wiki/cromulent

10:25 pixie79: Hi All - any ideas how i fix this clojure error ? - https://gist.github.com/pixie79/7677546

10:27 justin_smith: looks like SpoutConfig. expects the first arg to be an instance of BrokerHosts

10:27 ToBeReplaced: halogenandtoast: (map #(get-in % [:data :title]) (get-in json [:data :children]))

10:27 justin_smith: but it is a persistent list

10:28 halogenandtoast: So get-in is preferred over the arrow in this case (that or comp)?

10:28 justin_smith: pixie79: said list created on line 7

10:28 halogenandtoast: eh, it's kind of a style thing I think

10:29 ToBeReplaced: (map (comp :title :data) (get-in json [:data :children])) is okay, but is less clear imo b/c really we are talking about getting a key out of a data structure, not applying a set of functions

10:29 or threading data

10:29 justin_smith: ToBeReplaced: my most frequent usage of comp is as an arg to filter - to drill down to the sub-element in a collection that I want to be filtering on

10:30 comp is kind of a natural way to express finding some item nested in collections

10:30 ToBeReplaced: justin_smith: example?

10:30 justin_smith: (filter (comp even? :a) [{:a 0} {:a 1} {:a 2}])

10:30 ,(filter (comp even? :a) [{:a 0} {:a 1} {:a 2}])

10:30 clojurebot: ({:a 0} {:a 2})

10:31 justin_smith: having to filter by some part of a larger nested collection is something that comes up fairly often for me

10:32 usually more than one level of nesting, also

10:33 pixie79: I have no idea how to make an instance of BrokerHosts - that is my problem

10:33 ToBeReplaced: in that specific case i'd use comp as well -- for me, the difference is that you are applying a function to the element instead of retrieving the element -- the focus is on "even?" not the seq of keys

10:34 pixie79: as far as I can tell BrokerHosts is defined here - https://github.com/nathanmarz/storm-contrib/blob/master/storm-kafka/src/jvm/storm/kafka/KafkaConfig.java

10:34 which is the java module i am using

10:35 justin_smith: pixie79: looks like KafkaConfig.StaticHosts.hosts

10:35 if you can figure out how something gets added to that, you can then use it?

10:35 I could be wrong

10:35 jtoy: how can I install a library locally and then include it in all my projects without having to put it on clojars/maven?

10:36 justin_smith: jtoy: lein install

10:36 but then you need to lein install it on any machine where you want to use it

10:36 jtoy: justin_smith: that is fine for development, but how can I do this in a more scalable way if I dont want to put it on clojars ?

10:37 justin_smith: and having a particular coworker who I will not name here lein install while developing and forget to actually lein push to clojars is a source of more agony...

10:37 nDuff: jtoy: set up a local Maven repository, then.

10:41 pixie79: nope that makes me none the wiser on how to do it

10:41 dnolen: oh, optimizing for JS - https://github.com/clojure/clojurescript/commit/f69bc25720009f4727febacd0d6b77149a08926f

10:42 justin_smith: pixie79: maybe that convertHosts method is what you want

10:42 it needs a java list as input, so you need to turn your lazyseq into a java List.

10:43 and then feed it to that static method

10:43 I think

10:43 bbl, breakfast

10:43 pixie79: ok thanks

10:48 dnolen: moquist: there's not really a way to load libraries in the REPLs that ship with CLJS, long out standing ticket. Maybe fixed in 3rd party REPLs like Austin, cljs-node-repl?

10:48 jtoy: anyone know of any simple clojure libraries that cache to disk?

10:49 I want to pull in webpages and cache them to disk for the next call

10:53 alexyakushev: dnolen: David, I'm currently watching your g33ktalk about core.async, and there you mention that `filter` function you wrote is a channel version of conventional filter for sequences. But it is not equivalent since it is mutable (consumes values on the channel), right?

10:55 dnolen: alexyakushev: it's stateful, but it's not a mutable reference type - the statefulness of channels hardly matters in actual programs since you cannot act on it any general way.

10:57 alexyakushev: but yes, it not precisely equivalent - but close enough IMO when writing channel pipelines

10:57 alexyakushev: dnolen: That's what I thought, thank you for clarification. I'm just wondering if it makes sense to put bangs or some other clues to functions operating on channels, in order to avoid possible confusion; and if this confusion is dangerous at all

10:58 dnolen: alexyakushev: not useful, channel consuming produce functions produce values - the channel

10:58 alexyakushev: the actual channels ops are already marked

11:01 alexyakushev: dnolen: OK, I start to understand it now. Functions that go channel->global-loop or global-loop->channel are already marked, those that consume and return channels don't have to be marked

11:01 dnolen: Thanks again, I will go investigate core.async further now

11:02 dnolen: alexyakushev: you are correct that if you're not careful and you read from something someone else is also reading from you may get unexpected behavior if you are expecting to get all values.

11:02 but of course there are cases where this may not be important you

11:02 as well as core functionality for tapping a channel to avoid this

11:03 if that's the behavior you want

11:09 majyk: Is there a version of the jQuery externs file available for 2.0.x? I don't see one listed here: https://github.com/iplabs/closure-compiler/tree/master/contrib/externs

11:09 I'm sure Clojurescript developers aren't all using 1.9 branch

11:16 siscia: hi all, I have a weird problem with slurp + regex...

11:16 seangrove: dnolen: Very nice array enhancement.

11:17 dnolen: What about inlining other constants?

11:17 dnolen: seangrove: yeah we should do that

11:18 seangrove: should be more straighforward to implement now that we have *passes*

11:18 seangrove: dnolen: You should just make a list of things like that so you can start parallelizing the work amongst others ;)

11:18 siscia: i have a regex that DOES match the text if a copy-paste it in the repl, but it doesn't work if a slurp the file containing the same text...

11:18 seangrove: Do we have a generic way of dealing with constants across different optimization settings, etc.?

11:18 gfredericks: siscia: are the strings equal?

11:19 siscia: gfredericks: yest they are

11:19 allsystemsarego: how do I find out what the latest version of core.logic is, so that I can type the correct thing in project.clj dependencies?

11:19 siscia: i just slurp the file, and C-a, C-y in the repl...

11:19 seangrove: allsystemsarego: https://github.com/clojure/core.logic says it's 0.8.5

11:19 dnolen: seangrove: I think we should just optimize constants if advanced optimizations applied for now

11:20 seangrove: allsystemsarego: There's also lein ancient, which will tell you if there's a new release

11:20 allsystemsarego: seancorfield, thanks

11:20 dnolen: allsystemsarego: many contrib libs show dependency information on their README

11:21 allsystemsarego: dnolen, thanks

11:21 seangrove: dnolen: Yeah, that seems perfectly reasonable. Just thinking of how to avoid headaches for developers as we get more of these improvements.

11:22 (dec seancorfield) ; bastard gets all my thanks with his alphabetatically first name

11:22 lazybot: ⇒ 4

11:22 seangrove: (inc seancorfield) ; still like him and appreciate his work though

11:22 lazybot: ⇒ 5

11:22 seangrove: (inc seancorfield)

11:22 lazybot: ⇒ 6

11:23 seangrove: dnolen: Anyway, I haven't contributed much to cljs recently, wouldn't mind picking up a feature/bug/ticket to work on

11:23 dnolen: seangrove: I think what we have in place for :optimize-constants is fine

11:24 seangrove: trying CLJS-698 http://dev.clojure.org/jira/browse/CLJS-658 would be cool, source maps for browser REPLs

11:25 seangrove: going through and adding the requested warnings would be good too, usually easy to do if a little boring.

11:25 seangrove: dnolen: Adding warnings is fine, certainly did it before.

11:26 Will take a look at the browser-repl source maps

11:26 dnolen: seangrove: there's only a few really big things I'd like to see in the near term - :libs, :main, and optimizing away protocols

11:26 then there's needed brain storm about boot strapping directly to Node.js

11:30 seangrove: dnolen: Where are the requested warnings to be added?

11:31 dnolen: seangrove: protocol form validation

11:31 seangrove: but also a bunch warnings we don't do that we could do

11:31 seangrove: around deftype

11:31 seangrove: warnings about missing libs, missing macro files

11:31 seangrove: a lot of these are in JIRA

11:33 seangrove: dnolen: Yeah, I go through JIRA from time to time, see if there's anything that looks like something I could do in my freetime

11:37 dnolen: seangrove: I just added a bunch of protocol deftype issues that have been bugging me recently

11:38 seangrove: dnolen: Ok, I see them. I'll go through them this weekend then

11:39 dnolen: seangrove: also if you want to tackle the constants things, cool w/ me

11:39 seangrove: dnolen: Also, what optimizations do you use when developing? any?

11:39 dnolen: seangrove: when I'm actually writing CLJS I use no optimizations

11:39 seangrove: I'd like to turn on source maps (haven't used them personally yet), but the overhead is a bit high with :whitespace optimization

11:40 But I'm not sure how to include all the generated files in the html

11:40 dnolen: seangrove: unless I'm benchmarking - then :optimizations :simple :static-fns true

11:40 seangrove: recompile w/ :whitespace + :source-map should never be more than 3-4s

11:41 probably more like 2s

11:41 seangrove: oh but you're probably doing this on huge codebase?

11:41 seangrove: Ok, that's acceptable then. Was pleasantly surprised to see my :whitespace optimization on a small-ish codebase recompiling in ~0.5-1s

11:41 Will try turning on source maps

11:41 dnolen: seangrove: yeah source maps don't add much overhead

11:42 seangrove: But when avoiding any optimizations, do you manually add each generated js file to the html files you're working with?

11:42 dnolen: IME, but I haven't tried on huge amounts of CLJS

11:42 seangrove: not at all

11:42 seangrove: This is on a new project, so it's still pretty small

11:42 dnolen: seangrove: https://gist.github.com/swannodette/7678991

11:43 seangrove: you just need slightly different markup is all, easily configured if you have some webserver setup

11:43 seangrove: no manual inclusion required - it's way more productive, recompiled take tenths of second

11:43 s/recompiled/recompiles

11:43 even w/ sourcemaps

11:44 seangrove: Files are automatically concatenated that way though?

11:44 dnolen: seangrove: no, and there's no need

11:44 you have extremely accurate source maps

11:45 seangrove: But in that case, does example.js contain example.core and other namespaces as well? What if you example.utils, would that be a separate file you'd have to add a new <script> tag for?

11:46 dnolen: seangrove: heh, no, all of this is magically handled by the goog.require goog.provide stuff

11:46 seangrove: Ah, ok

11:46 dnolen: seangrove: they actually do something if no optimizations present

11:46 seangrove: Interesting!

11:46 dnolen: seangrove: http://swannodette.github.io/2013/11/07/clojurescript-101/

11:46 seangrove: ^ try this if you want to get a sense of my workflow

11:46 it's coffee-script responsive - sans first compile

11:47 seangrove: I think it was the behavior of goog.require that was the missing piece for me

11:47 dnolen: seangrove: admittedly :optimizations :none used to suck in the past, it's my goto now

11:49 seangrove: Hrm, source maps seems to consume 700% cpu and never completes an initial compile. Will have to check this out....

11:49 dnolen: seangrove: sounds weird

11:49 seangrove: Ah, well, OoM error, GC overhead limit exceeded.

11:49 2080 is the latest release, right?

11:49 dnolen: seangrove: what cljsbuild are you using?

11:50 seangrove: 1.0.0

11:50 Should I be on 1.0.1-SNAPSHOT?

11:50 dnolen: seangrove: 1.0.1-SNAPSHOT lets you use your own memory setting. But how big is this project?

11:51 seangrove: ~1000 lines of cljs, and one foreign lib (flotr2.js) if that matters

11:51 clojurebot: I don't understand.

11:51 seangrove: Also, there are two warning about using undeclared vars wich I need to clean up

11:51 dnolen: seangrove: a public project?

11:51 seangrove: And yeah, looks like 1.0.1-SNAPSHOT at least finished a compile

11:51 Sadly not

11:52 I'm ok with it not working since I don't have an immediate repro case

11:52 allsystemsarego: can someone help troubleshoot this core.logic issue: http://lpaste.net/96290

11:53 dnolen: allsystemsarego: you need to (require '[sample.core]) and (in-ns 'sample.core)

11:53 gfredericks: what happens if an agent's queue gets large? it grows until OOM?

11:53 dnolen: allsystemsarego: before trying anything

11:53 allsystemsarego: dnolen, thanks, I'll try it

11:53 tbaldridge: gfredericks: yes, OOM

11:54 gfredericks: tbaldridge: thanks

12:05 moquist: dnolen: OK; thx. I'll check out the other cljs REPLs.

12:09 gtrak: dnolen: so, I managed to make hacking cljs protocols work for js objects, assoc-in and update-in work fine, but I'm having some trouble with arrays->seqs and back. Do you have a quick hack to make something like (update-in js-object [:array-key] #(remove pred %)) do the right thing?

12:12 IndexedSeq is backed by an array, I imagine I'll have to copy the array for each seq op (doesn't bother me). The one I was trying to make work was (update-in rest), where the final assoc would end up calling clj->js on the returned value from a 'rest' call.

12:22 wondering if that's how others have done it :-)

12:52 dnolen: gtrak: I can't think of an easy way to make that work

12:52 trptcolin: is it correct to say that the ^{:once true} metadata in the future and delay macros is helpful because those fns get used asynchronously? i get that it allows locals clearing for closed-over locals, but not quite grasping the implications, i think.

12:52 gtrak: dnolen: that itself is valuable information, so I don't pull my hair out :-)

12:53 trptcolin: or should every macro that creates a fn really stick that metadata on?

12:54 justin_smith: trptcolin: every creation of a function that you know will only get called once

12:54 which is usually going to be in a macro yeah

12:54 hiredman: trptcolin: because the function is only called once, it can clear anything it has closed over after the first call, instead of needing to hang on to them incase it gets called again

12:55 justin_smith: trptcolin: otherwise each of those one off generated fn objects will effectively be a memory leak

12:55 hiredman: ,(let [x 1 f (fn [] x)] (f) (f))

12:55 clojurebot: 1

12:56 hiredman: feh

12:56 llasram: trptcolin: relevant blog post: http://clj-me.cgrand.net/2013/09/11/macros-closures-and-unexpected-object-retention/

12:56 gfredericks: can a core.async message producer detect that a channel is closed?

12:56 hiredman: I forget how to do :once

12:56 Bronsa: ^:once fn*

12:56 hiredman: ,(let [x :a f (^:once fn* ([] x))] (f) (f))

12:56 clojurebot: nil

12:57 hiredman: there we go

12:57 trptcolin: ok awesome, this makes much more sense and should've been obvious. thanks

12:57 Bronsa: yeah, with 1 there would be no locals clearing since it's a primitive

12:57 gfredericks: ,(let [x1 12, x2 :twelve, f (^:once fn* ([] [x1 x2]))] [(f) (f)])

12:57 clojurebot: [[12 :twelve] [12 nil]]

12:58 justin_smith: in "Clojure HIgh Performance Programming" Shantanu Kumar claims that PersistentVector is O(1) for conj, but O(n) for last

12:58 that makes no sense to me?

12:58 gfredericks: justin_smith: last is not optimized for vectors

12:58 hyPiRion: justin_smith: see how last is implemented

12:58 $source last

12:58 lazybot: last is http://is.gd/RzMqTn

12:58 clojurebot: Roger.

12:58 Bronsa: justin_smith: you want to use peek in that case

12:59 justin_smith: how can it do insertion to the end in O(1) but not get the last element in O(1)? that seems weird

12:59 Bronsa: ahh, so peek gets the end, nice

12:59 ,(peek [1 2 3 4])

12:59 clojurebot: 4

12:59 justin_smith: thanks all

12:59 gfredericks: I don't think insertion is technically O(1)

12:59 but O(1)-enough

13:00 trptcolin: ^^^ math

13:00 * justin_smith goes looking for his usage of last to replace it with peek

13:00 gfredericks: ,(peek '(range 20))

13:00 clojurebot: range

13:00 justin_smith: hah

13:00 gfredericks: ,(peek (range 20))

13:00 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentStack>

13:01 llasram: ,(peek (apply list (range 5)))

13:01 hyPiRion: O(log32 n) with a low constant factor

13:01 clojurebot: 0

13:01 llasram: ,(peek (vec (range 5)))

13:01 clojurebot: 4

13:01 gfredericks: I wonder how ofter persistent lists are used in programs

13:01 justin_smith: ,(peek (apply list (range 10)))

13:01 clojurebot: 0

13:01 gfredericks: hyPiRion: cuz it only does that once every 32 conj's amirite?

13:02 justin_smith: ,(class (apply list (range 10))) ; gfredericks - timing!

13:02 clojurebot: clojure.lang.PersistentList

13:02 hyPiRion: gfredericks: well, yeah, that's included in the low constant factor, but it has nothing to do with the branching factor

13:02 gtrak: heh, why don't we just fix 'last'? I can't see any downside in making it faster for some things.

13:03 hyPiRion: amortized it could probably be seen as O(1/32 log32 n)

13:03 justin_smith: gtrak: yeah, I think intuitively I kind of just expected that

13:03 hyPiRion: which is like, uh, O(1/160 log n)?

13:04 justin_smith: cool, glad I asked, thanks again all

13:05 allsystemsarego: Is there a way to run user-defined commands every time the REPL starts up?

13:05 gtrak: I'm reading through a 2012 mailing list thread on this, seems like it's a silly argument. I'd rather get burned occasionally by my choice of ds than be slow always.

13:05 justin_smith: allsystemsarego: I think :injections may be for that sort of thing

13:07 gtrak: 'last' is semantically, intentionally, more meaningful than 'peek'

13:07 justin_smith: allsystemsarego: specifically, :profiles {:dev {:injections [(code goes here)]}}

13:07 unless there is a profile that is more specifically for repls

13:07 * seangrove is not looking forward to performance tuning this client-side cljs app

13:07 allsystemsarego: justin_smith, thanks

13:09 gfredericks: gtrak: agreed.

13:09 for existing functions that are slow for some data structures and optimized for others, see count

13:10 dnolen: seangrove: for profiling/optimizing I recommend Google Chrome, :optimizations :simple, :static-fns true

13:10 justin_smith: gfredericks: that same book I was mentioning claims O(1) for all the standard collection types

13:10 gfredericks: justin_smith: for...insertion? count?

13:10 justin_smith: though it could be wrong - but overall the book looks well researched

13:10 gfredericks: count

13:11 gfredericks: justin_smith: if you don't include lazy seqs as collections, then yes

13:11 but lazy seqs are ubiquitous

13:11 gtrak: yea, I mean, I'd expect to get burned by my choice of ds, I wouldn't expect 'last' to be a seq thing, but something that matters for things with order and limited length. Seq is the only thing in clojure that may not have a last element, anyway :-).

13:11 gfredericks: gtrak: should last be fast on sets/maps?

13:11 justin_smith: ahh, yeah, lazyseq is not on that list

13:11 thanks

13:11 gtrak: I wouldn't use it that way, so I wouldn't care.

13:11 gfredericks: ^

13:12 gfredericks: "Performance of last on unordered data structures is undefined due to gtrak"

13:12 seangrove: dnolen: Thank you, I made a note for when the time comes. A bit worried about the amount of data the client has to deal with, and I'm not sure about the normal limits

13:12 technomancy: gfredericks: if they're sorted sets/maps

13:12 gtrak: gfredericks: :-)

13:12 seangrove: I'll find out soon enough though...

13:12 gfredericks: technomancy: yeah that'd be useful

13:12 technomancy: how does that work currently? (comp first rseq)?

13:12 dnolen: seangrove: you're sending a huge amount of EDN to the client or something?

13:12 gtrak: gfredericks: last is just first on unordereds :-).

13:12 technomancy: no idea

13:13 seangrove: dnolen: No, it's json which is parsed and then converted into clj data structures, but then running lots of filters, maps, reduces over it, etc.

13:14 gfredericks: gtrak: ...sorta

13:14 dnolen: seangrove: got, you've got reducers in CLJS too

13:14 seangrove: Trying to see how much we can keep client side to keep ui iteration fast. And then see if it's possible to pin point the bottlenecks and speed it up enough for daily use

13:14 Ah, yes, good point

13:14 gfredericks: gtrak: it would be weird if (last x) and (last (seq x)) didn't return the same thing

13:14 gtrak: gfredericks: I also think it's bad to rely on key order, but it's nice that keys followed by vals line up.

13:15 dnolen: seangrove: I would be surprised if those filter/maps/reduces are bottlenecks though - unless it's a crazy amount of data

13:15 seangrove: dnolen: I don't think it's a crazy amount of data, so it'll be interesting to start pinning it down

13:15 gtrak: gfredericks: I don't think that would be weird for unordered data. You wouldn't notice it until you impose an order.

13:16 dnolen: seangrove: I spent a ton of time optimizing lazyseqs some time ago - very close to JVM there under V8 and looks fine elsewhere

13:17 seangrove: dnolen: The GC pauses are definitely killers though

13:17 Regularly hitting ~1.3s of gc

13:17 Often one after another

13:18 Yeah, looking at the timeline view, looks like it's entirely dominated by continuous GC

13:18 Well, it'll be fun to deal with that later, but premature optimization and all that

13:19 dnolen: seangrove: ah interesting, we don't have locals clearing in JS

13:19 CLJS I mean

13:20 seangrove: though I suppose we could?

13:20 gtrak: gfredericks: I think the fact that (first x) and (first (seq x)) are the same is an implementation detail. Seqs shouldn't care about how they're created.

13:21 dnolen: seangrove: still this may be an argument to switch to reducers in the near term

13:21 gfredericks: gtrak: I don't have any reasons to disagree; I just find the current behavior endearing.

13:21 gtrak: yes, it's definitely convenient :-)

13:22 dnolen: seangrove: http://dev.clojure.org/jira/browse/CLJS-705

13:22 gtrak: but not simple

13:26 drorbemet: Hi, I am trying to pull parse large xml (> 200Gb) in clojure. Is StAX supposed to be the pull parser for the JVM? I tried to count the elements in a large xml file using clojure/data.xml which uses StAX, but I got an out of memory exeption. Do you know some code samples that show how to avoid building up large values in mamory while pull parsing xml in clojure?

13:26 gtrak: drorbemet: you're probably holding on to the root somewhere

13:26 aconbere: hey folks, I'm learning clojure and I have a simple irc server I'm writing to learn with. I have a parser that returns me results like (parse "USER a b c :d") => { :command "USER" :params ["a" "b" "c" "d"] }

13:27 this is a useful generic representation of a command, and easy to parse into and serialize from

13:27 but doesn't captture any of the semantics about the user command (like the meaning of a b c and d)

13:27 gtrak: drorbemet: if the head end of the seq is bound, then those elements can't be garbage collected, and the entire thing would have to fit in memory during a count.

13:27 aconbere: username hostname servername and realname respectively

13:27 drorbemet: gtrak: ah thanks that coud be, how do I avoid that?

13:28 aconbere: what are strategies people employ to specialize in these cases?

13:28 seangrove: dnolen: Thanks, watching the ticket. I'll get the functionality in place and then dive into performance issues.

13:28 drorbemet: gtrak: yes that makes sense

13:28 aconbere: so far I've come up with building records, or just making specific maps

13:28 S11001001: aconbere: you don't have to smash all your parse/serialize into one step

13:28 gtrak: drorbemet: be careful with locals (let), vars (defs).

13:28 drorbemet: gtrak: ok understood

13:28 justin_smith: aconbere: you can make a vector of keys for each command, and zipmap to create a map for each one

13:28 S11001001: aconbere: e.g. have a second step which translates from your :command :params representation to something more useful, and then back from that

13:28 Bronsa: seangrove: dnolen: the logic is complex but http://bit.ly/1c8YQZx http://bit.ly/1ifNYOF this is how I do it in tools.analyzer

13:28 gtrak: maybe pass the xml seq straight into count

13:29 aconbere: S11001001: right so I mean the way I would approach specialization is have a step that converts from the specialized representation to the easy to serialize one

13:29 S11001001: aconbere: it's fine to just make maps when starting out, don't mess with records right away

13:29 dnolen: seangrove: now that we have lot of type information in the AST we should limit clearing locals to locals bound to lazy seqs, and it should have a knob to disable it for debugging

13:29 S11001001: aconbere: yeah

13:30 drorbemet: gtrak: basically I want to chunk the xml into the "pages" it holds

13:30 justin_smith: ,(let [part-command [:command :message]] (zipmap ["part" "leaving"] part-command)) ; aconbere - one possibility

13:30 clojurebot: {"leaving" :message, "part" :command}

13:31 justin_smith: I got the order in zipmap wrong, but modulo that, hope it makes sense

13:31 aconbere: justin_smith: ha, no worries I can translate

13:31 drorbemet: gtrak: ok thanks, that was the hint I needed, have a nice day or night :-)

13:31 justin_smith: aconbere: then you can just define a vector of keynames for each command, and pick one based on the first element in the command sequence

13:32 et voila, structured data

13:32 aconbere: yeah

13:32 that seems pretty reasonable to me

13:32 at least starting out

13:32 thanks justin_smith S11001001

13:39 gtrak: drorbemet: if you want to lazily chunk the xml, maybe it's convenient to use 'partition'

13:40 or partition-by

13:40 drorbemet: gtrak: ok, I'll try that

13:41 gfredericks: So my guess is that detecting a full channel is best done by using alts!! with :default

13:42 justin_smith: gfredericks: wouldn't that just check if no other channel has data?

13:42 gfredericks: justin_smith: alts!! with just one channel

13:42 will return immediately if the channel can't take a message

13:43 the other question is how to detect the channel is closed

13:43 justin_smith: I thought alts!! was for input

13:43 gfredericks: you can use it for puts as well

13:43 justin_smith: ahh, so if it returns immediately, it must be a closed channel

13:44 gfredericks: no

13:44 it must be full

13:44 justin_smith: for puts

13:44 ok

13:44 gfredericks: if the channels closed it pretends that it worked

13:44 which I cannot fathom

13:44 there's gotta be some way to detect a closed channel but I haven't found one yet

13:45 justin_smith: I think the implied model of core.async is very much "launch messages into the ether and forget about them"

13:45 as far as the sender is concerned, at least

13:47 gfredericks: hmm

13:47 I guess if I'm shutting down a system I might not mind messages being lost.

13:47 hadn't thought of it that way

13:54 dnolen: gfredericks: if you get nil you know it's closed

13:55 gfredericks: there is no way to know beyond that, and from the sound of it there may never be.

13:57 gfredericks: dnolen: I'm talking about the writer, not the reader

13:57 Raynes: gfredericks: candlejack was he

13:58 gfredericks: Raynes: that's the most sense you've made all day

13:58 Raynes: I don't think I've said anything all day.

13:58 gfredericks: phew

13:59 justin_smith: sounds like we got that all cleared away

13:59 dnolen: gfredericks: seems like a weird to want to know if something you're pushing to is closed if you weren't involved it's construction in anyway

13:59 gfredericks: if closing matters that it seems like the channel you want to push to give you some means to know about that event

13:59 explicitly

14:00 gfredericks: dnolen: why would a producer not be involved in channel construction?

14:00 gtrak: speaking core.async, does anyone have a snippet demonstrating what to do with exceptions?

14:01 dnolen: gfredericks: if it's involved then the thing it constructed should give it capability to know explicitly

14:02 gtrak: setting a default error handler or somesuch

14:03 gfredericks: dnolen: I must not have any design sense about async yet, as I can't see why an alternate "explicit" mechanism is any better than being able to explicitly find out that the channel is closed

14:03 dnolen: gfredericks: control channels use them

14:03 gtrak: there are many error handling approaches, supervisor, or you can catch and write error to a channel, or provide an error control channel

14:04 gfredericks: dnolen: I can't parse that sentence, but I imagine you're suggesting if there's a function that creates a channel and writes to it until it's closed, I could achieve that by passing in a control channel that will get a single message when the other one is closing?

14:05 dnolen: gfredericks: yep

14:05 gtrak: dnolen: potentially, I could make a macro around try-catch, binding an error channel, to be used within a go-block? that sounds reasonable enough.

14:06 gfredericks: seems hard to avoid race conditions, but I don't think I have a use for this at the moment so that's okay

14:06 at least, if you care about knowing exactly what got onto the channel and what didn't

14:06 dnolen: gfredericks: this is generally true anyway

14:06 thus buffered channels

14:07 gfredericks: buffered channels don't help you know what got accepted and what didn't, do they?

14:07 dnolen: gfredericks: what I mean there are many cases where you'll lose information and that's OK

14:07 gtrak: hrm, what's a 'control channel'?

14:07 gfredericks: dnolen: okay, so caring whether the message is accepted is a design flaw?

14:07 dnolen: gfredericks: you'll just be fighting against the design

14:08 gfredericks: I'm just making sure that the intention is for me not to care about that

14:30 justin_smith: I have app state that I want to share between instances - what is the best way to ensure that it can be serialized and shared - put it all in vanilla clojure datatypes, define the print method and a reader for each record I want to serialize?

14:34 gfredericks: justin_smith: records are supposed to be serializable; what sort of failure are you worried about?

14:34 justin_smith: the one I am getting in my stacktrace

14:34 "Unreadable form"

14:34 maybe it is not the record that is doing it

14:35 that was my first suspect

14:35 gfredericks: check for a #< somewhere

14:36 I think that's the only place that error gets thrown

14:37 justin_smith: found it

14:38 #<JdbcClob...

14:38 thanks

14:41 gfredericks: have people centralized around a particular schema lib yet?

14:41 I think the two I know about are flatland/schematic and prismatic/schema

14:57 l1x: hi

14:58 anybody has any recommendation to split a file that has multiple json documents in it? http://www.githubarchive.org/

14:59 gtrak: l1x: cheshire has stream-parsing stuff

15:03 l1x: thanks

15:23 bitemyapp: and thank god for that.

15:32 eric_normand: pedestal questIon: starting a new app, should I use the 0.3.0 construct namespace? or stick with app, which looks like it is being replaced?

15:32 rkneufeld: eric_normand: "0.3.0 construct"?

15:33 eric_normand: rkneufeld: project.clj says it's 0.3.0-SNAPSHOT

15:33 rkneufeld: the tutorial is still using io.pedestal.app

15:33 rkneufeld: eric_normand: ahh, that. No, you should not try building an app with 0.3.0

15:34 eric_normand: rkneufeld: not ready yet?

15:34 rkneufeld: it's so much nicer!

15:34 rkneufeld: eric_normand: hehe, thanks. There is still a lot left to do

15:35 eric_normand: rkneufeld: aw, shucks. just got done reading the walkthrough and was ready to jump in

15:36 rkneufeld: Pace should probably pick up into december and the new year. Conj was crazy for all of us.

15:42 eric_normand: rkneufeld: I bet. Any word when it will be ready for bleeding edge consumption

15:42 rkneufeld: we've got an internal app (read: can have bugs) that we'd like to try it on

15:43 rkneufeld: Well, if you want to *bleed*, you could play with it now. I just don't suggest you do that ;)

15:44 Once I finish the book on the 10th I want to take a pass at reducing tooling quite a bit. It'd be amazing if dataflow was just a library you could use.

15:56 pwojnowski: Hi. I'm writing tests using clojure-test and it's ok for Clojure code, but now I need to mock Java classes. Can it be done in clojure-test? If not how to do it in Clojure?

15:57 gfredericks: pwojnowski: what part do you need to mock? you need classes that have particular named methods? implement particular interfaces?

15:58 pwojnowski: I have a WS port generated from WSDL and just want to return predefined response from it.

15:58 gfredericks: what does that mean in terms of classes/methods/interfaces? a "WS port" is a class?

15:59 how are you going to interact with the mock object?

15:59 pwojnowski: AFAIR it's just a class (no statics, finals), so simple mock should be enough.

15:59 justin_smith: if the port is an input stream, you could define a stream with the contents you want the port to return

15:59 pwojnowski: In Java I would just use Mockito or something like that.

16:00 seangrove: Ah, bummer, flatland/useful isn't available in clojurescript

16:01 gfredericks: pwojnowski: okay, what methods do you need on it? is there an interface associated with the methods?

16:01 justin_smith: seangrove: I see a future in "pure clojure" variants of the best libs

16:01 seangrove: I wish clojure had map-keys and map-vals was just in the language :P

16:01 bitemyapp: if anyone is wondering what maintaining an OSS project is like

16:02 it means time spent trying to read the tea leaves of other peoples' pull requests, trying to figure out what the hell they're fixing/adding/changing/removing

16:02 justin_smith: pwojnowski: you could just use mockito

16:02 pwojnowski: gfredericks: I don't remember at this moment, but lets say it a method doing some logic and I just want to return 42 from it.

16:03 justin_smith: I know that I can use Java libs, but I thought that there is some Clojure solution for this. But thanks anyway.

16:03 gfredericks: pwojnowski: it's easier if the method is defined on an interface; otherwise you might have to whip up something custom but I can probably do that in five lines

16:04 justin_smith: pwojnowski: there is no clojure solution for this

16:05 the need to stub classes comes from a bunch of java design decisions that are much less likely to apply in purely clojure code (ie. every defrecord makes a stateless constructor which makes mocking trivial)

16:05 cYmen: Good evening clojurians!

16:05 bitemyapp: cYmen: good morning

16:05 ~UGT

16:05 clojurebot: UGT is Universal Greeting Time http://www.total-knowledge.com/~ilya/mips/ugt.html

16:05 * cYmen empties a back of parens and brackets on the floor.

16:06 cYmen: Let's party!

16:06 cfleming: pwojnowski: do you provide the instance of the WS port class?

16:06 If so you could proxy it

16:06 bitemyapp: cYmen: I'm at work :P

16:07 mongodbfacts: Good thing the NPM repository is built with Node.JS, otherwise they might have needed $2MM to scale.

16:08 mongodbfacts: "writing JavaScript without npm: np-hard"

16:08 cYmen: bitemyapp: The competent *cough* people at where I work have blocked irc so I can only use it using the web client or with tunneling.

16:08 seangrove: Amazing some people haven't just been removed from the ml

16:08 bitemyapp: seangrove: thinking of that one bloke, what's his name...

16:08 greevey. cedric greevey.

16:08 he's a sloshy bucket of bile everytime I see him on the ML.

16:08 cYmen: all my IRC goes through ssh. *shrug*

16:09 mosh, specifically.

16:09 cYmen: bitemyapp: The really very competent people blocked ssh as well.

16:09 bitemyapp: gg.

16:09 llasram: cYmen: Where the heck do you work?

16:09 cYmen: iTunes of course is available because somebody important has an iPad...

16:10 llasram: I'm going to keep that secret so this doesn't turn into name-calling. :p

16:10 llasram: heh

16:10 bitemyapp: cYmen: never try to recruit me.

16:11 * llasram does some googling, and is frankly surprised

16:11 cYmen: about?

16:12 pwojnowski: Thanks everyone for help. I'll try to do it in pure Clojure.

16:12 * seangrove is likewise surprised

16:12 gfredericks: here's a probably buggy (in three different ways?) way to do mocks: https://www.refheap.com/21301

16:13 llasram: cYmen: Oh, probably name collision actually

16:14 cYmen: What did you find? :)

16:14 seangrove: 8th light?

16:14 bitemyapp: cYmen: https://github.com/cymen this you?

16:14 he writes clojure.

16:14 cYmen: no

16:14 bitemyapp: welp.

16:14 seangrove: Ok, that explains it then

16:15 cYmen: I certainly hope his clojure is better than mine.

16:15 seangrove: Was just strange that software craftsmen would block ssh

16:16 gfredericks: works a little better with definterface

16:19 oh weird. it works only when called at the top level

16:20 otherwise the interface name doesn't resolve

16:21 justin_smith: gfredericks: macros are weird

16:21 gfredericks: I think this is more about the compiler than the macro

16:22 huh...is reify* a special form?

16:23 looks like it is

16:23 TIL

16:24 okay if I resort to using eval to generate the interface at macroexpand time it seems to work and I don't know if there are any downsides

16:25 llasram: gfredericks: alternative:

16:25 Just actually call `definterface` during maroexpansion, then expand to code referencing the interface

16:26 gfredericks: llasram: how do you call definterface with a programmatically chosen interface name?

16:27 llasram: Oh, there's the rub. You'd need to call the lower-level `gen-interface`

16:27 freshhawk: leiningen newbie here, I've got some java files to import and i've got my :java-source-paths set up correctly (lein compiles them anyway) but I can't import them. Any ideas what I'm missing or what docs I need to read?

16:27 gfredericks: llasram: ...which is also a macro?

16:28 llasram: gfredericks: Yep, I have been wild-goosing you apparently

16:28 gfredericks: Have fun with eval :-)

16:28 gfredericks: the presumably final version: https://www.refheap.com/21301

16:29 magnars: how do you handle the "odd man out" in a chain of (-> threading macro functions) ? The single function that wants a ->> instead?

16:29 gfredericks: magnars: you can embed ->>

16:29 justin_smith: magnars: I use as->

16:29 gfredericks: or alternatively use as->

16:29 magnars: thanks, I'll look into those :)

16:29 gfredericks: ,(-> 3 (+ 5) (->> (- 100)) (* 2))

16:29 clojurebot: 184

16:30 magnars: of course, that makes sense

16:30 gfredericks: hard to think up on your own though

16:30 justin_smith: ,(as-> 3 n (+ n 5) (- 100 n) (* n 2))

16:30 clojurebot: 184

16:30 justin_smith: slightly longer, I find it easier to read

16:30 magnars: yeah, that was interesting.

16:30 gfredericks: also more flexible; the ->/->> thing doesn't work the other way

16:31 not to mention when you have more than a couple args. I often resort to as-> when I'm using reduce

16:31 because it goes in the middle

16:31 magnars: exactly

16:31 gfredericks: ...sometimes

16:32 bitemyapp: as-> is lovely.

16:32 * gfredericks always names the thing <>

16:32 jared314: can you name it ?

16:33 "?" ?

16:33 bitemyapp: -> is the Winchester.

16:33 justin_smith: hell, you could name it ☃

16:33 gfredericks: ,(as-> "x" ? (str "bwaaz" ?))

16:33 clojurebot: "bwaazx"

16:34 justin_smith: name it $* and pretend you are writing a shell script

16:41 hiredman: b

16:42 bitemyapp: ahhh nothing like rewriting quickcheck in Python for the 5th time.

16:42 We have done this before...and we are growing exceedingly efficient at it...

16:43 justin_smith: is that more or less fun than tracking down the various ways clobs are sneaking into the things you create from your db data I wonder

16:45 bitemyapp: justin_smith: clobs?

16:45 justin_smith: http://docs.oracle.com/javase/tutorial/jdbc/basics/blob.html

16:46 bitemyapp: justin_smith: what the fuck

16:46 :|

16:46 justin_smith: we had some coming back from a query, everything was good until the result of the query had to go in an avout distributed atom

16:46 and they are not serializable

16:47 devn: blech -- i can't figure out what's up with my cider and eldoc

16:47 I keep getting this in the minibuffer: eldoc error: (void-function -elem-index)

16:48 justin_smith: have you tried setting debug-on-error to a truthy value?

16:48 it will pop up a stack trace and let you see the el source where the problem happened

16:48 and you'll be all like "this is a lisp language, I know this" and you'll fix the bug

16:49 coventry: justin_smith, devn: Someone was complaining about this error in cider here a few weeks ago.

16:49 cYmen: Hm...any hints for this: http://www.4clojure.com/problem/146

16:50 I can't even figure out how to use for on maps.

16:50 devn: is eldoc maybe a dep on nrepl?

16:51 err no, it's a built-in

16:51 hmmm

16:51 magnars: devn: seems like you're missing dash. Try a M-x package-install dash

16:51 justin_smith: ,(for [[k v] {:a 0 :b 1}] [k k (* v 2)]) ; cYmen

16:51 clojurebot: ([:a :a 0] [:b :b 2])

16:51 seangrove: ,(into {} (for [[k v] {:a 0 :b 1}] [k (* v 2)]))

16:51 clojurebot: {:a 0, :b 2}

16:52 technomancy: elisp without dash =(

16:52 magnars: it's harsh

16:52 devn: magnars: hmm, i never needed it before?

16:52 I upgraded from nrepl to cider

16:52 justin_smith: if that is the case, cider should add an explicit requirement for dash

16:53 devn: That fixed it. Thanks magnars.

16:53 cYmen: justin_smith: I came so close to guessing this syntax correctly. >_<

16:53 devn: <3

16:53 technomancy: justin_smith: it does

16:53 magnars: It is an explicit dependency of cider, but something's gone wrong somewhere.

16:53 technomancy: at least on master

16:54 bitemyapp: Wheeeee reduce(dict_conj, zip(*[string_seq(num_pairs)]*2), {})

16:54 llasram: bitemyapp: `reduce` in Python? You dare oppose the will of the BFDL?

16:54 devn: bitemyapp: heh

16:54 technomancy: ~guards

16:54 clojurebot: SEIZE HIM!

16:54 bitemyapp: llasram: I actually just tweeted the code at him.

16:55 devn: lol

16:55 llasram: niiice

16:55 justin_smith: samizdata reduce

16:55 devn: stick it to the man

16:55 justin_smith: smuggled past the python border

16:55 bitemyapp: I'm not happy about being back to writing Python at work, but I can make the most of it.

16:55 now I just need a short-circuiting reduce.

16:55 time to make a foldr!

16:55 brehaut: bitemyapp, llasram: we all know that you should be writing a class that implements __add_ with your reduction and just use sum. its much clearer

16:56 monoids for all!

16:56 justin_smith: just hearing that kind of logic makes me feel like my reasoning skills have been abused

16:57 bitemyapp: brehaut: you're right, but I hate you for making it sound silly.

16:57 technomancy: http://wingolog.org/archives/2013/11/26/a-register-vm-for-guile <- andy wingo is always fun to read

16:58 wink: yup, I read that at 12 am my time already :P

16:58 still wonder why I always used to read his blog via planet python

16:58 the non-python stuff is much more interesting

16:59 technomancy: heh; I found it on planet.gnome.org =)

16:59 wink: I love gnome as a concept

16:59 devn: This might come in handy for some of you: http://en.wikipedia.org/wiki/Tall_poppy_syndrome

16:59 wink: but I can't stand using their stuff anymore (mostly WM etc, apps are fine)

17:00 technomancy: wink: their infrastructure is fine even if you don't like gnome-shell

17:00 but yeah, I mostly read it to follow what's going on in free software land more than anything else

17:00 wink: hey, it's just a lame excuse that I don't have to skim 100 more blog posts a day ;)

17:01 it's still interesting, but I don't need/want gnome3

17:01 llasram: The first chart in that post is awesome

17:01 wink: so amaze

17:01 bitemyapp: very graph

17:02 technomancy: I've pretty much given up trying to understand what software for normal people should be like.

17:02 so I respect the gnome folks even if it's not for me

17:02 wink: devn: Tall poppy syndrome doesn't apply to bitemyapp though. He's just - in general - grumpy

17:03 technomancy: man, this post makes me wish I had an excuse to dive into some scheme

17:04 hyPiRion: I dug into Guile because... I needed to learn automake

17:04 technomancy: or maybe I should just write a lisp that targets guile bytecode

17:04 wink: s,everbody and his dog,everybody and his lisp,

17:04 bitemyapp: doge lisp

17:04 technomancy: wink: I already have a toy lisp impl; it's ok

17:05 wink: although LISPs are, to my knowledge, not yet sentient

17:05 bitemyapp: too bad it's too terse. the syntax doesn't lend itself to be replaced by so/much/wow

17:06 you need a language where you could replace ; with "wow" or if with so much

17:06 magnars: so interface much generics wow

17:06 wink: actually that's been so often it would be cooler to write a meta-meme language

17:06 *done

17:07 a DSL to transform memes into languages

17:07 my head is spinning

17:07 * technomancy steps away before he's implicated in the scene of a crime

17:08 * bitemyapp drops http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html on the floor and runs away

17:10 * wink has to think of free willy now

17:11 wink: "the little monad that could"

17:12 technomancy: haha; cider's version in master is "0.4.0-cvs"

17:12 the heck

17:12 wink: you can't delete it, you have to move it to the attic?

17:12 justin_smith: it's the branch they work on while using the free wifi at their neighborhood cvs pharmacy

17:14 bitemyapp: Hrm. recursing in Python is hella awkward.

17:15 wink: why?

17:15 clojurebot: why is the ram gone

17:15 wink: m(

17:15 bitemyapp: wink: no TCO, despite having a VM that could've done it.

17:15 wink: no loop/recur equivalent either.

17:16 wink: clojurebot: because they're taking the hobbytes to isengard, silly

17:16 clojurebot: Huh?

17:16 bitemyapp: so I have to write a while loop. Fantastic.

17:16 mattmoss: Oh great, now that song is stuck in my head. Thanks, wink.

17:16 wink: mattmoss: blame the bot

17:16 technomancy: It's Pythonic.™

17:16 wink: bitemyapp: ah that

17:17 bitemyapp: technomancy: sanity draining.

17:17 mattmoss: The bot looked confused to me.

17:17 bitemyapp: tedious and petty.

17:19 mattmoss: (into isengard (take 2 hobbitses))

17:19 bitemyapp: man this code is silly.

17:32 cYmen: Is this https://www.refheap.com/21304 an appropriate solution for 4clojure 146? I'm not sure what the lesson is supposed to be here or if I understand the problem correctly.

17:34 justin_smith: cYmen: that looks like it solves it, and if it does, yeah, looks great

17:35 cYmen: It passes the tests.

17:35 justin_smith: it's about learning how to massage your data into the structure you need

17:35 cYmen: That's all I can say. :)

17:35 justin_smith: you could generalize to N depth

17:35 but the problem is explicitly only for a fixed depth of 2

17:35 cYmen: I also have no idea how to generalize it to depth n :)

17:35 justin_smith: recursion!

17:36 cYmen: Well, yeah that almost always works. :)

17:36 justin_smith: generalized depth == recursion :)

17:36 for fixed depth you can explicitly unroll as you do here

17:37 wink: If in doubt, recurse.

17:41 justin_smith: cYmen: that answer is a lot nicer than mine

17:41 I just finally checked, mine sucks

17:42 https://www.refheap.com/21305 do not emulate this crappy code

17:42 though it does work

17:43 cYmen: oohhh...I need to friend you or whatever it is one does on 4clojure

17:43 I always want to look at other peoples solutions but don't know anyone.

17:43 justin_smith: I

17:43 'll return the favor

17:44 cYmen: What's your account name?

17:45 justin_smith: noisesmith (as mentioned on that refheap)

17:45 cYmen: hmpf

17:45 I tried that. :)

17:45 justin_smith: it automatically generates a refheap from the share button if you solve one of the items

17:45 cYmen: Ah I needed to show all first.

17:45 justin_smith: yeah, I am not in the top 100

17:46 cYmen: Just expected it to extend that when searching. Whatever.

17:47 JaredR: first day here... a friend is a hardcore clojurian, I'm still wrapping this imperative brain around FP... it currently hurts, but it seems to be a worthy pursuit. :)

17:47 `cbp: welcome

17:47 JaredR: just joined up on 4clojure... cYmen and justin_smith can I add you guys as friends?

17:47 justin_smith: yeah, please do

17:48 cYmen: Sure, my account name is "Firefly" but I am just almost through the easy problems myself...

17:48 But I'd love to talk about alternative solutions and stuff. :)

17:48 JaredR: finding this extremely helpful in the absorption of the concepts: http://www.defmacro.org/ramblings/fp.html

17:49 `cbp: clojurebot: what is good in life?

17:49 clojurebot: excusez-moi

17:49 JaredR: thanks guys... and ooh, a fellow browncoat? :D

17:49 bitemyapp: JaredR: that's a good intro, but the rabbit hole goes much deeper :)

17:49 JaredR: yeah, I've done the FIRST problem. lol I got it right though. hehe

17:49 bitemyapp: oh look, he even says, "This article only scratches the surface of functional programming."

17:50 justin_smith: cYmen: capitalized or no?

17:50 I found a non-capitalized firefly

17:50 cYmen: justin_smith: Does it matter? I think just firefly.

17:50 justin_smith: ok, searching for capitalized found nothing

17:50 cYmen: JaredR: browncoat? What?

17:50 justin_smith: just making sure

17:50 firefly has not seen firefly

17:50 JaredR: Firefly... umm... heh never mind.

17:51 bitemyapp: JaredR: I'm a browncoat, if that's any comfort.

17:51 justin_smith: cYmen: I recommend watching firefly, it is a good tv series

17:51 JaredR: yay! cYmen WRT Firefly the TV show... fans refer to themselves as browncoats.

17:51 cYmen: I've seen Firefly. Just didn't know the name for fans. :)

17:51 JaredR: also, after the series, watch Serenity, the movie, the "final episode" of the show.

17:52 justin_smith: dude, they even talk about browncoats in the show, you couldn't have watched that closely

17:52 cYmen: justin_smith: It's been 5 years or something....

17:52 insamniac: I watch lots of shows and don't remember everything from said show

17:52 wink: I also never heard the term in regard to fans

17:52 insamniac: Hell, I just watched Firefly this year and don't remember browncoats

17:52 wink: ah well, at least it's not reavers :P

17:53 JaredR: here 5 minutes and already I drag the conversation off topic. lol

17:53 wink: offtopic would be pet grooming

17:53 but not firefly!

17:54 JaredR: browncoats is a term only comes up once in a while... most specifically in the bar scene later in the series. they're in a bar on the anniversary of the big battle that Cap'n was in, and the alliance guys in the bar are ripping on "browncoats"

17:54 justin_smith: I just got caribou core caching compatible with avout, so with the middleware that is almost ready, one will be able to run multiple caribou instances that have their concept of the data models in sync

17:54 in other words, win

17:54 cYmen: A caribou is still a bird in my world. :p

17:54 bitemyapp: justin_smith: wait, you're using avout for caching?

17:55 insamniac: lulz caribou bird

17:55 wink: wait what

17:55 JaredR: caribou is a chain of coffee shops... they cache coffee.

17:55 justin_smith: bitemyapp: a special variant of caching: the data model for all stored data is cached so that it does not need to be retrieved as a prereq for every request

17:55 bitemyapp: cYmen: a caribou is a ruminant mammal with antlers.

17:55 justin_smith: I've clearly not dived into this corner of Caribou.

17:56 JaredR: bitemyapp: also known as a reindeer.

17:56 justin_smith: a problem we had was multiple instances, sharing a db, would move their models out of sync, such that when one instance expanded or modified the model schema, the others would get exceptions

17:56 bitemyapp: so far as I was aware, it was a hybrid web framework/CMS that you used with a database.

17:56 justin_smith: a changes feed works great here.

17:56 justin_smith: cache in the process, asynchronously update when the changes feed says something needs updated.

17:56 justin_smith: that was my first approach

17:56 bitemyapp: okay, what went wrong?

17:57 JaredR: that's getting more specific, yes.

17:58 justin_smith: bitemyapp: the existing updates were already expressed in terms of swap! (we had been using an atom) and I realized it would be simpler to use avout/swap!!

17:58 and just treat the avout data as a distributed atom

17:58 and in fact it's class is distributedatom

17:58 * nDuff perks ears up

17:59 justin_smith: if this ends up being a performance hit, from using the shared data model, I will go back to a change feed

17:59 nDuff: Has there been any work on Avout? Last time I looked, it didn't have any kind of exception handling support.

17:59 justin_smith: nDuff: its last changes are old, but I haven't run into any issues yet

17:59 bitemyapp: justin_smith: couldn't you just add a watch and cache the atom state locally?

18:00 justin_smith: I successfully turned some atoms in my codebase into avout/zk-atom s

18:00 bitemyapp: justin_smith: I'm not saying pre-optimize until you've got a benchmark and data, just speculating.

18:00 nDuff: justin_smith: are you relying on cases where exceptions are thrown from within transactions that modify refs?

18:00 bitemyapp: because right now you're just dereferencing on the fly right?

18:00 justin_smith: nDuff: no refs, just an atom

18:00 *some atoms

18:00 bitemyapp: right

18:01 bitemyapp: justin_smith: so you're still creating a potential overhead in requests.

18:01 justin_smith: that'll probably fly until you topple the poor ZK cluster over.

18:01 then you'll want to subscribe to atom state as a changes feed (add watch)

18:01 justin_smith: I turned the code that used reset! and swap! into usages of a simple protocol, then I inject avout's version of the protocol from the client app

18:01 bitemyapp: still don't know why you need this, interesting as it is :)

18:02 justin_smith: bitemyapp: when I an the frontend guy are hammering away at a new site, he will add a data model

18:02 or I will

18:02 or better yet, add or delete or modify a field in a model

18:02 since the information about the models is stored

18:02 we get sql errors if our concept of the data model goes out of sync with the db

18:02 this keeps things consistent during dev

18:03 and also, if it performs well enough, can help us coordinate multi-server deploys

18:03 and maybe even rolling upgrade, etc.

18:03 bitemyapp: hrm, yeah, I have a decidedly different way of handling this.

18:03 that involves a lot less code.

18:03 justin_smith: though the things synchronized on the deploys will not be data models, which should not change in production

18:03 cYmen: hmpf

18:03 justin_smith: but things like client data

18:04 bitemyapp: your method is datomic, no?

18:04 bitemyapp: haha, no, I'm thinking of SQL databases.

18:04 justin_smith: so tell me about your approach

18:04 bitemyapp: justin_smith: I maintain/work on Clojure libraries for three different kinds of databases.

18:04 Datomic, RethinkDB, Korma.

18:04 justin_smith: I just take the fuckin' servers down and migrate the database, redeploying the new code :P

18:05 justin_smith: remarkably enough, I have done this also :)

18:05 bitemyapp: I've been going to some trouble to figure out how to do datomic migrations with minimal downtime.

18:05 justin_smith: the issue is that caribou allows model definition from within the cms - that is the model schema itself is data in the db

18:06 bitemyapp: you've recreated EAV. gg.

18:06 justin_smith: so something like avout helps that stay in sync

18:06 bitemyapp: seriously.

18:06 that's EAV.

18:06 add a T and you're halfway to reimplementing Datomic.

18:06 justin_smith: we have talked about ditching it all and moving over to datomic, though we are logging data model changes to create migrations so that is a step toward t

18:07 bitemyapp: yeah but this is a lot of code to be responsible for that doesn't actually bring the benefits of Datomic.

18:07 justin_smith: right

18:07 bitemyapp: Datomic does a great job of handling user-defined models due to its EAV heritage.

18:08 justin_smith: I am not claiming this is the most beautiful design. but it has succeeded in helping us develop apps very quickly and eliminate bottlenecks in development workflow, so we carry on

18:08 we are seriously considering abstracting out all sql dependencies

18:08 JaredR: justin_smith: not to distract from this illuminating convo... but how do I find and add someone on 4clojure?

18:08 justin_smith: in fact I have decided on that, and just have to implement it

18:09 JaredR: change the top 100 view to all users and use the search box

18:09 bitemyapp: justin_smith: I don't doubt you guys work quickly, but I've noticed that the more talented a programmer or group of programmers are, the more likely they get into an unnecessary complexity trap that their talent is masking.

18:09 *cough C++ cough*

18:09 justin_smith: bitemyapp: this is the truth

18:09 I have no doubt out design has reached a local minima

18:09 bitemyapp: maxima?

18:10 it's reached the pinnacle of what makes sense for this overall approach right? that'd be a maxima.

18:10 justin_smith: minima of unneeded complexity

18:10 or close to it

18:10 locally :)

18:10 but we do like to step back and reevaluate the big decisions

18:11 I have threatened ever since I got hired to re-implement the whole thing in ocaml or maybe haskell

18:11 speaking of the big decisions

18:11 bitemyapp: I'll help if Haskell.

18:11 justin_smith: I'll keep that in mind, thanks

18:11 bitemyapp: justin_smith: main frameworks to draw inspiration from (IMHO) would be Snap, Scotty, and Happstack.

18:12 Scotty is basically a routing Monoid, Snap and Happstack are built on combinators.

18:15 justin_smith: I'm considering porting a Clojure app to Haskell before releasing the official version of it for a variety of reasons, one is that the lack of a type system allowed things to get out of control.

18:15 I can report back my experiences in diving into the web stacks of Haskell when I do so.

18:16 justin_smith: cool

18:16 bitemyapp: I'm working on a command-line app in Haskell as well.

18:19 justin_smith: It is kind of cool to have two repls and a ring server, each in their own vm, and interact with them and see all applicable state reflected transperently between the three

18:19 I'll keep a lookout for those issues with refs though

18:20 but so far avout has been perfect for my usage

18:23 bitemyapp: justin_smith: yeah the only thing that I don't really like about Haskell is no equivalent (yet) to an embedded nrepl.

18:25 octagon: hi! i'm looking for an example or docs that explain how to access the cljs analyzer from a macro. any pointers?

18:29 bitemyapp: justin_smith: I take that back, you can wrap: http://hackage.haskell.org/package/hint

18:29 justin_smith: and just expose a secured client to it.

18:32 justin_smith: bitemyapp: cool

18:33 octagon: what does the macro need to do?

18:33 noprompt: hai

18:34 bitemyapp: noprompt: welcome back to the homeland

18:34 wink: bitemyapp: reading neubite source (because of the user-middleware question yesterday) - could you explain https://github.com/bitemyapp/neubite/blob/master/src/neubite/middleware.clj#L46 ? :)

18:34 bitemyapp: noprompt: I'm currently convincing justin_smith to rewrite caribou in Haskell and plotting the downfall of Simonides.

18:34 noprompt: bitemyapp: well, i've convinced my new coworkers that clojurescript is the answer.

18:34 bitemyapp: wink: provides a hook point for disabling/logging wrappers

18:35 noprompt: eggscellent.

18:35 noprompt: bitemyapp: boy, you sure are in haskell lately. don't pee in your pants.

18:35 bitemyapp: noprompt: I plan to work on either Simonides (in Haskell) or Grom with a buddy of mine. If you want in on the Haskell hack-fest let me know.

18:35 noprompt: :P

18:35 wink: bitemyapp: hm, I mean.. why not use apply directly in lines 51/56 - future expansability by encapsulation?

18:35 noprompt: bitemyapp: sure, why not? i'd be down.

18:35 bitemyapp: wink: it's to enable clean AOP/override/hooking/logging.

18:35 noprompt: bitemyapp: what kind of a rollout do i need for emacs?

18:36 wink: bitemyapp: ok, thanks.

18:36 bitemyapp: noprompt: best environ I've found: https://github.com/nominolo/scion

18:36 wink: I don't do OOP generally, I do AOP when I need the ability to extend/modify/override.

18:36 wink: comes from having been a ruthless CL user.

18:36 noprompt: bitemyapp: why haskell though?

18:37 bitemyapp: noprompt: too much of my Clojure has entailed getting into the weeds with type errors lately.

18:37 losing patience for it.

18:37 wink: bitemyapp: for that size it looked a lot like premature optimization, just how I would do it. so I thought I had missed something :P

18:37 bitemyapp: not just NPE (although definitely that too), all kinds.

18:38 wink: I didn't give it much thought beyond being my default approach when I write handler wrappers in Clojure.

18:38 cYmen: grmpf...how do I delete the next (...) with paredit?

18:38 do I have to enter it and delete with C-k M-s?

18:38 bitemyapp: wink: I provide a way to AOP the inner invocation behavior of wrapper HOFs.

18:38 just how I code

18:38 dnolen: cYmen: C-k

18:39 cYmen: oh from the one you are in? don't know how to do that, I guess slurp and C-k

18:39 noprompt: bitemyapp: interesting. i seldom have issues with type exceptions beyond NPE. although lately i've been wanting to investigate core.typed.

18:39 dnolen: bitemyapp: you know there is a Haskell channel for you to rant in

18:41 bitemyapp: dnolen: I'm stealing people first.

18:41 dnolen: bitemyapp: considering the smash up job you're doing - I'd give up while you're ahead

18:43 bitemyapp: dnolen: sho-thang ◕‿↼

18:43 akurilin: Is there way of completely omitting a form from a macro if I want to? For example, I'm calling Korma's (select mytable (order :id :ASC)) and I might want to completely omit the (order) part on a condition.

18:43 so that effectively it looks exactly like (select mytable).

18:43 bitemyapp: akurilin: compose it?

18:44 akurilin: bitemyapp, oh yeah, hmm let me look into that

18:44 bitemyapp: ~fcomp is have you tried function composition?

18:44 clojurebot: Cool story bro.

18:44 bitemyapp: ~fcomp

18:44 clojurebot: I don't understand.

18:45 bitemyapp: ...

18:45 ~botsmack

18:45 clojurebot: clojurebot evades successfully!

18:45 akurilin: bitemyapp, forgot about that select* option

18:45 bitemyapp: Wow, bot is snotty today.

18:45 ~fcomp

18:45 clojurebot: Pardon?

18:45 bitemyapp: ~fcomp is have you tried function composition?

18:45 clojurebot: excusez-moi

18:45 bitemyapp: I give up.

18:45 ~zergling

18:45 clojurebot: zergling is https://github.com/prismofeverything/schmetterling

18:45 bitemyapp: okay so it hasn't gone totally nuts.

18:46 noprompt: dnolen: i've been messing around with core.async and pubsub to do two-way data-binding. part of the little system i've built uses atoms to store application state when specific messages are published. do you know if there are any drawbacks to this sort of design?

18:46 bitemyapp: global mutable state seems like a drawback.

18:47 noprompt: bitemyapp: or a tradeoff.

18:47 bitemyapp: If it's a good fit for your problem, so be it, but there are alternatives.

18:47 I think I know what you're talking about, I can see why you'd want to do that.

18:47 noprompt: bitemyapp: this is the discussion i'm looking for.

18:48 bitemyapp: noprompt: you can do a fanout of listeners instead of an atom/

18:48 (I had to pause to think about this)

18:48 generally people care about a model's state because they either need to read it now, or get an update when it happens.

18:48 so rewrite in terms of something more reactive and let state propagate via channels.

18:49 dnolen: noprompt: could work - I'm pretty curious about React.js's approach these days thanks to prodding from bbloom

18:49 bitemyapp: you could do a hybrid approach too.

18:50 noprompt: this would be easier to explore over a skype convo or something, do you get where I'm headed though?

18:50 noprompt: bitemyapp: well yes, techically i can remove the atom and the system will continue to work just as it does now. occasionally, the state is of interest.

18:50 bitemyapp: right but that's what I'm saying, you subscribe listeners to a fanout channel of updated state.

18:51 everything gets bucket-brigaded via channel, no need to atom-smash.

18:51 noprompt: dnolen: i haven't looked at React.js but i will. essentially what i am trying to do is a controllerless angularjs style framework with cljs. i've been working on it for a little while now and mostly this is the part that concerns me. the compiler/parser/directive stuff was really not that difficult.

18:52 the offerings of purnam and clang are hackish ugly ideas to me.

18:52 bitemyapp: noprompt: what I'm talking about would eventually move you towards something like React.js'ish

18:52 dnolen: noprompt: just read through the first page - http://facebook.github.io/react/

18:52 SegFaultAX: Is React.js similar to RxJs?

18:52 * SegFaultAX opens google

18:52 bitemyapp: although my mental model for something like this is typed, not untyped, and is more like Elm.

18:52 noprompt: wrapping a framework is silly.

18:52 dnolen: noprompt: maybe you can do something like this?

18:52 noprompt: lemme take a look.

18:52 dnolen: noprompt: React.js basically has a functional represenation of the DOM, a virtual

18:52 one

18:53 noprompt: turns out it faster to to diffs on the virtual DOM than it is to touch it!

18:53 touch the real DOM

18:53 noprompt: so kind of production quality version of WebFUI if you saw that

18:53 noprompt: dnolen: that's interesting.

18:54 dnolen: noprompt: yeah I don't really care about the other bits - but the batching of render ops, and the virtual DOM, those are solid ideas

18:54 noprompt: their JSX stuff is basically Hiccup

18:54 except ugly HTML in your code

18:55 noprompt: dnolen: yeah, eww, just saw that.

18:55 dnolen: noprompt: yeah skip all that, and look at the big ideas - I think they're pretty solid

18:56 akurilin: bitemyapp, not sure I quite got this pattern down. Is this was you were thinking? https://www.refheap.com/21310

18:56 noprompt: bitemyapp: we should definitely skype or gangout regarding the simonides hackfest.

18:57 SegFaultAX: akurilin: Ew, that's some ugly threading.

18:57 akurilin: Are you on 1.5 or above?

18:58 bitemyapp: noprompt: <3

18:58 akurilin: SegFaultAX, I'm all ears about how to make that better :) Thinking macro, but there's probably a better way.

18:58 SegFaultAX, yes

18:58 bitemyapp: woof.

18:58 SegFaultAX: akurilin: as-> is a thing.

18:58 noprompt: dnolen: though the popular idiom in js is to use $ prefixed vars for dom selections, it's kinda cool you could actually do something like (let [<p> ($ "p")] ...) in cljs, heh heh.

18:59 dnolen: noprompt: heh

18:59 noprompt: definitely easier to spot than $p

18:59 akurilin: SegFaultAX, do you know of any examples of that being used?

18:59 SegFaultAX: But angle brackets in a symbol is going to get annoying to type after about 10 seconds.

19:00 bitemyapp: DOM variables get dem dollas.

19:01 noprompt: dnolen: btw, are the closure docs wrong? i see that gdom/$ and gdom/$$ are deprecated and there is now a gdom/query function, however, that doesn't seem to be the case. :-/

19:01 gdom/query doesn't exist but the others do.

19:01 dnolen: noprompt: it's in third party and in order to get at it you gotta use :import because of the weird Closure coding style conventions

19:01 (:import [goog.dom query])

19:01 noprompt: SegFaultAX: as-> is awesome. fuck haters, i love as->.

19:01 SegFaultAX: akurilin: It just gives a name to the value to be threaded through, then anywhere that symbol is given will be subbed.

19:02 noprompt: dnolen: ah, sweet! thanks.

19:02 bitemyapp: noprompt: who doesn't like as->? Can we burn them?

19:02 SegFaultAX: (as-> (...) foo (do-something foo) (do-something-else 1 2 foo 3))

19:02 noprompt: bitemyapp: ah, i can just imagine some fool going off about it.

19:02 dnolen: noprompt: oh, but it's no in 2080 yet, so you want that to work you'll need to install master

19:02 SegFaultAX: noprompt: If you love as-> then you'll probably also appreciate synthread.

19:02 dnolen: s/so/so if

19:03 bitemyapp: noprompt: http://www.haskell.org/haskellwiki/Emacs

19:03 noprompt: SegFaultAX is right, synthread is cool. topic monads ftw.

19:03 noprompt: dnolen: sure thing. no worries. i usually wrap that sort of thing so when i upgrade, etc. i only need to change code in one place.

19:03 SegFaultAX: Can we take all the Haskell stuff to #haskell? As much as I love Haskell, this isn't the place for it.

19:03 akurilin: SegFaultAX, cool thanks, will give it a shot

19:03 bitemyapp: SegFaultAX: noprompt isn't in #haskell

19:03 he wanted to know how to set up his Emacs.

19:04 technomancy: he's missing out

19:04 bitemyapp: technomancy: you're not in #haskell either

19:04 noprompt: lol.

19:04 SegFaultAX: noprompt: /join #haskell, n00b

19:04 * noprompt actually laughed out loud.

19:04 technomancy: yeah, but I know how badly I'm missing out already

19:04 noprompt: SegFaultAX: it's all good. #clojure is enough irc at one time for me.

19:05 SegFaultAX: noprompt: Yea, but that channel is quite unlike every other channel on freenode.

19:05 Well, except maybe #math

19:05 technomancy: he's definitely missing out by not being in #emacs too; geez

19:05 noprompt: SegFaultAX: i've been there a few times. it's cool.

19:06 technomancy: life is always passing me by.

19:06 SegFaultAX: Has anyone tried pulsar/quasar?

19:06 As a replacement for core.async in particular.

19:07 bitemyapp: SegFaultAX: I don't know if I'd think of it as a "replacement"

19:07 SegFaultAX: they have some overlap but are suited to different kinds of problems.

19:08 noprompt: dnolen: how close are we to seeing a self hosted cljs compiler?

19:08 SegFaultAX: Not really.

19:08 Pulsar apparently comes with a compatability layer that exposes an identical API to core.async.

19:08 noprompt: bitemyapp: on the client side there is definitely *no* replacement.

19:08 SegFaultAX: But fundamentally it's coroutines for the JVM.

19:09 Like, real coroutines.

19:09 noprompt: if there isn't a #celeryman there should be.

19:11 "this" has become one of my least favorite words.

19:11 SegFaultAX: In the context of objects?

19:12 noprompt: SegFaultAX: mostly in the context of javascript objects.

19:13 SegFaultAX: noprompt: Ugh, tell me about it. Javascript is so mindcrushingly horrible (sorry dnolen), and the semantics around `this` make up a large part of the horrible-ness.

19:13 JaredR: justin_smith: still around?

19:13 lnostdal: "connecting to nREPL on localhost:52224...", but nothing happens .. strange .. no logs in any emacs buffer that i can see (emacs, clojure-mode, cider)

19:13 justin_smith: JaredR: yeah, what's up?

19:13 glosoli: lnostdal: latest version ?

19:14 noprompt: in a traditional class based object oriented world, if i drop a glass on the floor how does it break?

19:14 does the glass have method for breaking itself?

19:14 how do i model this?

19:15 * noprompt is not trolling. lol.

19:15 JaredR: your solution for 4clojure #9 - sets conj was (inc 1)... explain please? :)

19:15 lnostdal: glosoli: yes, i think so .. M-x package-list-packages tells me "cider 20131127" is installed

19:16 JaredR: justin_smith: your solution for 4clojure #9 - sets conj was (inc 1)... explain please? :)

19:16 SegFaultAX: noprompt: Assuming the target is IBreakable, sure! :)

19:16 glosoli: lnostdal: weird I just updated to that same version, seems to be working

19:17 SegFaultAX: lnostdal: Can you connect to the nrepl directly?

19:17 noprompt: dnolen: why was :imported decided to ony work with goog?

19:17 JaredR: justin_smith: never mind... lol. I thought 1 was a reference to something, but it's just the literal. lol... so was there a reason other than cleverness for that answer?

19:17 noprompt: err :import.

19:17 bitemyapp: noprompt: Elm's tutorials teach reactive thinking nicely. Have you seen them?

19:17 justin_smith: JaredR: I was likely being a smartass

19:18 I got bored but wanted the easy stuff marked as done

19:18 bitemyapp: noprompt: http://elm-lang.org/learn/What-is-FRP.elm http://elm-lang.org/Examples.elm

19:18 JaredR: justin_smith: roger. lol. thanks for breaking my newb brain. heh

19:18 noprompt: bitemyapp: a while back yeah. but other than factor or prolog i'm really not interested in dicking with another language right now.

19:18 lnostdal: SegFaultAX: you mean just `lein repl` from the CLI? yes, that works

19:19 SegFaultAX: or wait, i'll try lein repl then connect to that from emacs

19:19 bitemyapp: noprompt: I'm not saying to *use* Elm, I'm saying to let it convey a way of thinking.

19:19 SegFaultAX: noprompt: Factor you say!? What got you on that?

19:19 noprompt: bitemyapp: ah yes.

19:19 SegFaultAX: lnostdal: Yes that.

19:19 lnostdal: I should have been clearer: can you connect to a running nrepl session.

19:19 noprompt: SegFaultAX: it looked interesting.

19:20 SegFaultAX: noprompt: I'm also interested in it. From a purely "oh, that's kinda neat" perspective, though.

19:20 I would never actually do anything meaningful in it.

19:21 lnostdal: SegFaultAX: ok, nope; same thing .. stuck with the same "connecting to nREPL..." message

19:21 noprompt: SegFaultAX: i like to pick up a new language each year in a paradigm i haven't explored.

19:21 SegFaultAX: noprompt: Let me just say this though: the factor pastebin is a cesspool. Stay as far away from that place as you can.

19:22 noprompt: SegFaultAX: roger that.

19:22 SegFaultAX: did you hear about gershwin? https://github.com/gershwin/gershwin

19:23 irctc: whois

19:23 whoami

19:23 lazybot: irctc

19:23 SegFaultAX: noprompt: Yup. I'm sure you've heard of bbloom's factjor? https://github.com/brandonbloom/factjor

19:24 noprompt: SegFaultAX: sure did. in fact bbloom's talk is what got me interested in looking at factor in the first place.

19:24 SegFaultAX: Likewise.

19:25 noprompt: SegFaultAX: i haven't messed with gershwin yet but like the idea.

19:25 SegFaultAX: I wonder if there are people that do actual work in a language like that. Not just fun-time hacking but like mission critical stuff.

19:25 Well, other than Forth.

19:25 noprompt: SegFaultAX: i'd bet there's some FORTH out there.

19:25 SegFaultAX: Shitloads.

19:26 bitemyapp: god fucking dammit melpa.

19:26 SegFaultAX: Solaris, FTW.

19:26 bitemyapp: another dependency vendored, another reason to hate MELPA. *scratches a tally on the prison cell wall*

19:27 noprompt: correction, don't use Scion.

19:27 SegFaultAX: melpa is the emacs thing?

19:27 bitemyapp: SegFaultAX: it's one of the emacs things that exist.

19:28 noprompt: bitemyapp: ok.

19:28 SegFaultAX: bitemyapp: Does package.el not know how to dependency or something?

19:29 noprompt: bitemyapp: i should ask @dysinger. he uses emacs and haskell.

19:29 bitemyapp: noprompt: I do too, but I'd never expanded beyond haskell-mode since 2010.

19:29 I wanted to check on the IDE functionality for your sake, turns out the cool kids use ghc-mod now.

19:29 partly because haskell-mode subsumed shime.

19:30 SegFaultAX: Just ask in #haskell.

19:30 bitemyapp: before anybody complains, he's still not in #haskell.

19:30 too late.

19:30 SegFaultAX: Or Twitter.

19:30 noprompt: SegFaultAX: i just asked @dysinger.

19:30 bitemyapp: I just told dysinger what I'd found so far.

19:30 noprompt: SegFaultAX: he's cool guy.

19:30 bitemyapp: and doesn't afraid of anything.

19:30 noprompt: lol

19:32 bitemyapp: python is janky language btw.

19:32 bitemyapp: itertools; garbage.

19:32 SegFaultAX: itertools is gold.

19:32 noprompt: SegFaultAX: a gold turd.

19:32 technomancy: SegFaultAX: emacs dependencies are "just grab me the latest; cool" and melpa treats git master as fine to package, so you can imagine the breakage that abounds

19:32 SegFaultAX: Given what the language provides in __builtin__, itertools and functools are gold.

19:33 technomancy: Ah, golang style deps. Got it.

19:33 bitemyapp: without itertools and functools I would constantly cry bloody tears while writing Python.

19:33 noprompt: SegFaultAX: in the context of python sure. in the context of everything else, turds.

19:34 immutability is like heroin.

19:34 bitemyapp: "everything else" have you used anything that wasn't functional recently?

19:34 SegFaultAX: noprompt: Python isn't a functional language to the extent of Clojure or Haskell or Scala or ML.

19:34 noprompt: SegFaultAX: originally i think it was supposed to be a functional language.

19:34 bitemyapp: mori for Python would be kinda cool.

19:34 noprompt: it wasn't

19:34 SegFaultAX: noprompt: Nope. Never.

19:35 bitemyapp: noprompt: my Common Lisp brothers tried to force it on Guido, he got really mad.

19:35 noprompt: that's why he whines about reduce.

19:35 SegFaultAX: noprompt: filter/reduce/map were added by a disgruntled lisp hacker and will likely be removed.

19:35 tos9: noprompt: It's not. When we want functional we write clojure :)

19:35 (Or at least I do)

19:35 noprompt: tos9: it's not like heroin?

19:35 bitemyapp: I write functional'ish in Python.

19:36 noprompt: tos9: or itertools is not turds?

19:36 SegFaultAX: tos9 knows. He's idled in #python at least as long as I have. Probably longer.

19:36 bitemyapp: ༼ つ ◕_◕ ༽つ Give functional

19:36 tos9: noprompt: It's [Python] not [functional]

19:36 noprompt: itertools is certainly turds :)

19:37 SegFaultAX: tos9: Compared to what (in Python)?

19:37 noprompt: tos9: exactly what *is* python? i mean, seriously? what is it?

19:37 SegFaultAX: noprompt: A language.

19:37 noprompt: SegFaultAX: i guess.

19:38 SegFaultAX: it's definitely the 3rd worst language i've messed with.

19:38 technomancy: a cult? =)

19:39 SegFaultAX: noprompt: I've been writing Python for about 8 years now. I have issues with it, but I don't hate it /that/ bad. What are 1 and 2 on your worst list?

19:39 * tos9 bets on VB

19:40 seangrove: Honestly, clojurescript with an eye for performance and a sane ui metaphor/interface, and I wouldn't mind spending the vast majority of my time developing in the browser

19:40 arrdem: python gets the job done and people can read it. makes for a great interview language :P

19:40 noprompt: php and js are the top two.

19:40 seangrove: The UI is the missing piece here.

19:40 arrdem: noprompt: perl should have 3...

19:40 noprompt: well maybe php and c++.

19:40 bitemyapp: Python is nicer than JavaScript.

19:40 noprompt: c++ was the first language that actually made my blood boil.

19:40 seangrove: ClojureScript makes all the other hard lifting fine, doing some pretty intense data manipulation and filtering stuff that would be nightmarish in js.

19:40 SegFaultAX: noprompt: PHP and JS are good choices. C++ though?

19:41 seangrove: Well said. I would extend that over Clojure, too. Clojure is easily the best data modeling language I've ever used in my life.

19:41 akurilin: What's an elegant way of comparing items in two vecs at the same index, from beginning to end? I can ghetto it up with map-indexed, but I imagine it'd be more along the lines of interleave + take-nth 2

19:41 noprompt: SegFaultAX: a compiler that tells me my problem is on line N of some file F while in fact the error is on line M in file G. yeah, fuck that.

19:41 SegFaultAX: akurilin: Map is variadic.

19:41 technomancy: noprompt: you've never had that happen in clojure?

19:42 seangrove: MongoDB C++ php ruby emacs eclipse iod templating npm node

19:42 bitemyapp: ,(into {} (map vector [:a :b :c] [0 1 2]))

19:42 clojurebot: {:a 0, :b 1, :c 2}

19:42 SegFaultAX: noprompt: Clojure does that all the time.

19:42 bitemyapp: akurilin: ^^

19:42 * seangrove ducks and runs away

19:42 noprompt: SegFaultAX: you forget a semicolon in c++ and it's like good luck!

19:42 SegFaultAX: noprompt: Wow, that's an unbelievably minor complaint.

19:42 Relative to all the things you could have said about C++

19:42 arrdem: yeah. templates are so much worse than the semantic choise to use ; deminimated statements.

19:42 akurilin: SegFaultAX, bitemyapp wat.. you tell me now about this?! :)

19:43 SegFaultAX: akurilin: Given your newfound knowledge, see if you can work out the solution. :D

19:43 bitemyapp: akurilin: you should do 4clojure puzzles.

19:43 you'll find new toys.

19:43 SegFaultAX: Yup.

19:43 Or Clojure koans.

19:43 (Well, /and/ Clojure koans)

19:43 justin_smith: and read code written by amalloy

19:43 akurilin: seems like a good idea, thanks for the tip

19:43 bitemyapp: that too.

19:44 noprompt: SegFaultAX: well there was definitely more. templates. linking hacks. other random weird shit. i've only used in algorithms classes so for all i know it might be a decent language.

19:44 technomancy, SegFaultAX normally when i get an error in clojure i don't look at the line numbers.

19:45 SegFaultAX: noprompt: The most significant amount of C++ I've ever done was a cross-platform (Android+iOS) mobile rendering engine with Lua bindings. C++ has its shortcomings for sure, but ; isn't on the top 100. :)

19:45 technomancy: noprompt: because you've been subliminally trained that it's gonna be useless already =)

19:45 dnolen: noprompt: port of tools.reader, macros, faster multimethods, Node.js based IO

19:45 noprompt: re: optional bootstrapping to JS

19:46 seangrove: "They should really move forward because JavaScript is becoming new IE6."

19:46 Today's wat.

19:46 dnolen: noprompt: what good is :import except for Clojure

19:46 noprompt: technomancy: that's probably it!

19:46 SegFaultAX: seangrove: The next ecmascript actually has some pretty cool features.

19:46 Generators in particular are pretty neat.

19:47 octagon: dnolen: do you know of an example of using the cljs analyzer from inside a macro?

19:47 noprompt: dnolen: i was just curious to know the motivation. i've been out of the loop for the passed couple months.

19:47 clojurebot: No entiendo

19:47 seangrove: SegFaultAX: Yeah, saw Eich's talk in JSConEU. Some nice compile-target feature, but the syntax was pretty unpleasant looking (destructing, etc.)

19:47 noprompt: *past

19:47 dnolen: SegFaultAX: no offense taken re: JS I like it in the small, but I get tired of it when writing more than a thousand lines or so

19:48 SegFaultAX: dnolen: Out of curiosity, do you use cljs at work?

19:48 dnolen: noprompt: motivation for bootstrapping? writing Clojure sans JVM when there's value to that.

19:48 akurilin: SegFaultAX, Apparently I was trying to re-implement compare. "leverage", is that right, bitemyapp?

19:48 dnolen: SegFaultAX: no, most of the JS I write at NYT is of the trivial variety, we don't do many "apps"

19:48 noprompt: dnolen: no motivation for limiting :import to goog.*.

19:48 *no,

19:49 dnolen: noprompt: oh, what else would it be used for?

19:49 SegFaultAX: dnolen: What is most of the stuff you hack on at NYT?

19:49 dnolen: noprompt: at one point we allowed importing a deftype but it caused more problems not less

19:49 SegFaultAX: JS, HTML/CSS, Ruby on Rails

19:49 SegFaultAX: dnolen: Ah, just your run-of-the-mill full stack guy? Me too. :)

19:50 dnolen: octagon: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L205

19:50 SegFaultAX: yeah the whole team is on Rails, though currently there's been a lot of grumbling, but Rails is convenient and there's not a great replacement that doesn't suffer from the same problems

19:51 SegFaultAX: dnolen: Same at Rally.

19:51 dnolen: SegFaultAX: for services there's excited about Go, which is fine. Some talk about Node.js which sounds awful to me - for apps I'd take Ruby over Node.js any day.

19:51 well JS in Node.js anyway

19:51 CLJS in Node.js another story

19:51 octagon: dnolen: perfect! thanks a million! i'm trying to see if i can detect when a form is a macro or not from inside my macro, without doing a full macro expansion

19:51 dnolen: this should get me started, thanks

19:52 SegFaultAX: dnolen: Have you given much thought to transitioning into something that would allow you to use CLJ[S] full-time?

19:53 bitemyapp: SegFaultAX: even if he had it's unlikely he'd say so in public.

19:53 SegFaultAX: I thought about that the moment I asked.

19:53 Heh

19:53 bitemyapp: doing cljs full-time would probably mean doing less interesting cljs stuff than he currently does.

19:53 SegFaultAX: dnolen: Not trying to put you on the spot, just asking since you're so heavily involved in the clojure community at all levels.

19:54 bitemyapp: so I don't think it would necessarily make sense.

19:54 SegFaultAX: dnolen: Anyway, nevermind. :D

19:54 seangrove: cljs for small apps could make a great deal of sense, if only we had the ui down.

19:54 noprompt: the guys at the shop i just started at seem like they're excited about me bring clojurescript to the table.

19:54 seangrove: Certainly fine as it is, but this has been bubbling up for a bit now

19:54 dnolen: seangrove: agreed, it'll happen in there near future I suspect

19:55 s/there/the

19:55 noprompt: once i showed them core.async the whole "it looks weird" argument started to fade quickly.

19:56 seangrove: dnolen: Yeah, I have some experiments I've been working on, need to grab some ios devs to get a better understanding of how ui is generally/properly done

19:57 dnolen: seangrove: iOS stuff is well designed component wise, but control is still a mess - instead of callback you have lots of delegation and proliferating APIs

19:57 around delegation

19:57 seangrove: dnolen: Thinking more in terms of the controls metaphors

19:58 Working on that + something like webcomponents + pedestal's functional-as-long-as-possible approach

20:00 dnolen: octagon: the ability to call the analyzer from a macro in CLJS and get something easy to work w/ is my favorite less well known feature of CLJS

20:00 seangrove: sounds awesome

20:00 noprompt: dnolen: wait. what?

20:00 dnolen: octagon: the ad-hoc shenanigans can die

20:01 noprompt: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L205

20:02 akurilin: Is loop a way to avoid defining and then calling a recursive function?

20:06 noprompt: i look forward to the day when macros can be written in cljs.

20:07 hyPiRion: they can?

20:08 noprompt: hyPiRion: not yet.

20:08 hiredman: I've played a little with tools.analyzer.jvm for "compiler" type macros in clojure it seems workable there too

20:09 hyPiRion: what do you mean by "not yet"? https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async/macros.clj

20:09 dnolen: hiredman: right, nice

20:09 hyPiRion: Perhaps I joined the conversation at some strange point

20:10 dnolen: hyPiRion: he means mixing macros into the source file

20:10 hyPiRion: ooh

20:10 dnolen: which will be low priority as there's a lot of churn involved in that which isn't necessary for boostrapping to JS

20:11 noprompt: dnolen: so 2014? :-)

20:11 dnolen: noprompt: I don't see why not

20:12 seangrove: The cljs-in-cljs project looks quite cool, but I imagine it's diverged so far from master at this point merging would be painful and massive

20:33 justin_smith: hlship: I don't know if you are around, but I'd like to talk to you about integrating twixt as a drop in extension to caribou at some point - I want to look into it on my own first, I'll likely have some questions

22:37 bitemyapp: http://erlang.org/pipermail/erlang-questions/2013-November/076112.html

22:39 noprompt: bitemyapp: "welcome to Computing :-)" lol

22:39 bitemyapp: noprompt: but clearly PHP is the superior choice for numerical problems.

22:40 seangrove: Well, only thing left to do is work on distributed PHP systems

22:40 justin_smith: didn't python change at some point from the erlang behavior to the php one?

22:41 bitemyapp: I don't know. Wouldn't surprise me.

22:41 justin_smith: I must be misremembering

22:41 bitemyapp: because fucking with floats is "less surprising"? :P

22:41 justin_smith: my python does the erlang one

22:41 noprompt: python is the new php.

22:42 seangrove: noprompt: We can only hope so.

22:42 That's a positive progression at least.

22:50 I think the latest message on the ml could possibly qualify for a clojure wat bot.

22:51 justin_smith: the clueless contractors have discovered clojure

22:51 yay

22:51 tbaldrid_: seangrove: is that the lisp to java class?

22:51 Raynes: https://groups.google.com/forum/#!topic/clojure/eociVedmzuE

22:51 seangrove: tbaldrid_: yeah, specifically the LISP portion

22:52 justin_smith: Or the markov chains are being pointed at ml's now.

22:52 justin_smith: someone get him a copy of the original McCarthy LISP stat

22:53 bitemyapp: If somebody doesn't know what month of the year (off by 5 months) the major holiday of their home nation occurs in, are they a spy?

22:53 bbloom: oh boy.

22:53 bitemyapp: noprompt: hey

22:54 justin_smith: bitemyapp: could be a very busy child prodigy who has been so busy with med school and law school and being a virtuoso painist that they never really learned anything about the normal world

22:54 it happens

22:54 bitemyapp: noprompt: /join #haskell

22:54 justin_smith: physics major that decided to code for a living.

22:54 seangrove: I tried my hand a being a viruoso painist, but found the S&M clubs a bit too dirty for my tastes

22:56 justin_smith: http://i.imgur.com/ecCEQ04.jpg

23:09 technomancy: yesssss https://github.com/clojure-emacs/cider/tree/content-types my precious

23:12 emaphis: wow, hot of the press. :-)

23:23 technomancy: hawt

23:26 bbloom: technomancy: ok sooo i heard some mention of nrepl and content negotiation

23:26 what are you up to you maniac?

23:32 mercwithamouth: wrong place to ask but is common lisp good for writing scripts?

23:33 noprompt: javascript:{}

23:34 bitemyapp: mercwithamouth: I use Haskell and Python for that. you could use nodejs + cljs too.

23:34 mercwithamouth: using packages in CL is too annoying for me to use it with scripts.

23:40 technomancy: bbloom: racket envy?

23:40 mercwithamouth: bitemyapp: gotcha. i was hoping to start using a lisp for scripts

23:41 bbloom: technomancy: i saw the recent post & skimmed your link above. give me the 5 sentence summary of what you hope to realistically achieve in a way that reaches a large portion of the clojure community

23:41 go!

23:41 noprompt: mercwithamouth: cljs + node is not a bad target.

23:41 mercwithamouth: https://github.com/guns/optparse-clj

23:42 justin_smith: on the latest osx you wouldn't even need node theoretically

23:42 noprompt: justin_smith: go on.

23:43 technomancy: bbloom: porting slime's inspector to nrepl; monitoring middleware that can provide svg graphs inside the editor; maybe some kind of game that could use images for tiles; incanter-type stuff.

23:43 justin_smith: noprompt: https://developer.apple.com/library/mac/releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_9.html

23:43 someone has to connect clojurescript to it of course

23:43 but I am sure someone will do that

23:44 technomancy: bbloom: there's two sides to the problem; one is moving more logic that has been traditionally editor-side into the server, but that depends on the server being able to send stuff back to the client using something less primitive than stdout

23:44 bbloom: technomancy: so i'm not totally familiar with nrepl's internals, but how much of it is "repl" and how much of it is standard embedded debugging server ?

23:45 justin_smith: noprompt: looks like a js interpreter embedded in osx / ios, which you could target with your clojurescript, I assume

23:45 bbloom: technomancy: b/c what you're describing sounds like the latter

23:45 technomancy: bbloom: also: you can rip out a ton of custom elisp in cider and replace it with clojure-side equivalents. slamhound.el, clojure-test-mode.el, and cider-trace.el can be totally ephemeralized; replaced with server-side stuff that isn't tied to emacs

23:46 bbloom: this is the groundwork you would need to be able to write a portable debugger

23:46 bbloom: technomancy: makes sense to me, so maybe i'm tripped up on the name of the thing having REPL in it :-P

23:46 technomancy: bbloom: it's part of the P in REPL

23:46 read eval display loop

23:47 bbloom: so where does the content-type part come in?

23:47 technomancy: need a richer display mechanism than println

23:47 bbloom: i'd expect return values to be *clojure values*

23:47 not arbitrary content

23:47 justin_smith: the difference as I see it is that with a dt-socket you totally control the target vm, to the degree of stopping / starting / manipulating the stack and bytecode

23:47 noprompt: justin_smith: oh yeah, i heard about this.

23:47 bbloom: although i could understand uber stdin/stdout as messages instead of byte streams where each message has a content type

23:47 justin_smith: while this is an interpreter built into the program, not a direct control on the vm

23:47 technomancy: bbloom: an nrepl middleware could come up with a better way to render a given clojure value

23:47 bbloom: but i don't want (+ 1 1) to return content-type number :-P

23:47 technomancy: haha; sure

23:48 but you don't want everyone to have to reinvent a bunch of rendering logic either

23:48 justin_smith: for example, if you halt the target vm, you can't really count on the nrepl in that vm helping you at all

23:48 bbloom: i don't trust most ppl to write sane middleware

23:48 try printing a large object in chrome

23:49 change obj.x to some new value

23:49 then expand the object in the console

23:49 the x will be the LATER x, not the one at print time

23:49 yeah, that's a js issue

23:49 but so many people are all excited about "object shells" and other silly things, i get concerned :-P

23:50 technomancy: I haven't heard that term

23:50 we're just talking about various representations of a given return value

23:50 justin_smith: technomancy: think like that old xterm from the mozilla project that could display a jpg or mpeg inline when you cat the file

23:50 technomancy: it's kind of restful in that regard

23:50 justin_smith: that's an object shell

23:51 technomancy: justin_smith: gotcha. yeah that makes sense to me.

23:52 bbloom: i'm worried about not having control over return values representations w/o loading some custom lib and whatnot

23:52 technomancy: bbloom: just adjust the accept header that your client sends then

23:52 bbloom: no i mean right now how i handle this is by returning nil and printing w/ pprint or whatever

23:52 justin_smith: bbloom: isn't your issue about expecting live vs. static display? think gdb where you can have a watch, and that updates its display constantly vs. a trace that shows a log of each value

23:53 bbloom: justin_smith: i'm mostly rambling

23:53 justin_smith: as long as you have informed consent to which you get, I don't see the problem

23:53 bbloom: i've had a long day :-P

23:53 but yeah, i really don't want live displays in my repl. i want it to be a log

23:53 technomancy: this is about "we have some data. it's more readable as an svg, but you can have it as edn if that's how you roll. do you grok svg? k, here's an svg."

23:54 bbloom: ok the real issue i'm concerned about is stdout vs return values

23:54 * justin_smith hears the sound of 1000 emacs user turning off svg display compatibility.

23:54 bbloom: right now if i want to print something pretty, i (pprint ...) which return snil

23:54 returns nil*

23:54 pprint writes text, explicitly

23:54 i could see (svg-print ...) or whatever too

23:54 technomancy: bbloom: plus it's all up to the nrepl handler to decide how it renders things. the eval operation is probably never going to return anything other than a textual representation, but you can add other operations than eval.

23:55 bbloom: but what about return values?

23:55 like if i do (load-image ...)

23:55 and that returns a Bitmap or something

23:55 technomancy: bbloom: then it depends on what nrepl middleware you install

23:55 bbloom: what happens? some middleware intercepts and renders it as image/jpg ?

23:55 technomancy: and what accept headers you send

23:55 but there's no way we'd interfere with eval operations out of the box

23:56 bbloom: i guess what i'm saying is that i want complete control and predictable behavior for both return values and "emitted" (in leu of "printed") values

23:56 technomancy: I'm thinking more like M-x inspect-class -> results in a non-eval nrepl op being invoked that returns hypertext

23:56 bbloom: ok, so it sounds like you're only talking about eval

23:57 stuff that you enter directly into a repl

23:57 justin_smith: what about some extension of pr / print

23:57 bbloom: yeah, sorry, i don't use emacs & i have litterally one repl interaction: evaluate this range of text

23:57 technomancy: I'm talking about using nrepl as a transport by which you can invoke any kind of server-side op

23:57 bbloom: yeah, sure i get that

23:58 nrepl is probably just a misleading name at that point, but fine

23:58 if you don't fuck w/ the eval case at all and don't provide an API for emitting things, then i've got no further input to add

23:58 technomancy: yeah, it's a generic async protocol that happens to be used primarily for eval; kind of like how emacs is a generic lisp runtime that happens to be used primarily for editing

23:59 bbloom: ok

23:59 technomancy: "don't provide an API for emitting things" what does that mean?

Logging service provided by n01se.net