#clojure log - Dec 25 2013

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

0:01 logic_prog: argh

0:01 apparetly I need one terminal for "lein cljsbuild auto"

0:01 and another for "lein cljx auto"

0:02 rovar: you could maybe pdo them both?

0:03 lein pdo cljb auto, cljsbuild auto,

0:03 or something to that effect

0:12 logic_prog: rovar: lein-pdo is awesome!

0:12 I used to have a tmux with 3 terminals

0:12 for "lein run main", "lein cljsbuild auto", and "lein cljx auto"

0:13 rovar: it is rather helpful, I've found

0:13 logic_prog: I tried for the longest tie to get "lein do" to do multiple things that don't return

0:13 gave up, and then assumed it couldn't be done

0:23 sorry for dumbass question: does #+clj go until #+cljs , and #+cljs go until end of the sexp?

0:23 i.e. how doe #+clj and #+cljs decide when to terminate?

0:29 ivan: logic_prog: they apply to the next token, no?

0:29 rovar: I don't even know what you're referring to

0:29 ivan: https://github.com/lynaghk/cljx

0:30 logic_prog: ivan: ah, got it working, thanks!

0:47 egosum: is there a way to use functions as predicates in core.match? seems like that just might not be doable?

0:50 ddellacosta: egosum: got an example of what you want to do in a gist/refheap? Also, looked into this? https://github.com/clojure/core.match/wiki/Advanced-usage#extending-pattern-matching

0:50 egosum: ddellacosta: that isn't working for me; let me throw it in a gist

0:50 i'm not sure it's possible with the way match is implemented, but i've just started looking at it tonight. give me a minute

0:51 ddellacosta: k

0:54 egosum: ddellacosta: https://gist.github.com/ihodes/8120514

0:55 ddellacosta: egosum: gimme a sec, let me get a repl going

0:55 egosum: ddellacosta: no worries, thanks for checking it out :) appreciate it

1:00 ddellacosta: oh, I see, I misunderstood--you're talking about evaluating a function in the result

1:00 egosum: sorry, that was to you ^

1:01 egosum: in the result? i'm not sure i follow

1:01 i'd like to evaluate a function in the decision tree that match generates

1:01 a predicate function

1:01 ddellacosta: sorry, nevermind--one sec

1:04 egosum: it works with vars, but not with function definitions of any sort

1:04 so it's not a showstopper

1:04 logic_prog: >! puts to the _end_ of a channel

1:04 rovar: the way I read the advanced usage.

1:04 logic_prog: is there a way to push to the _front_ of a channel ?

1:04 rovar: logic_prog: like a priority message?

1:05 logic_prog: i.e. something like (let [msg (<! ...)] ... oh crap, we cna't handle msg, we need to push msg back into the chan at the front)

1:05 rovar: oh

1:05 logic_prog: rovar: I may be in the X-Y problem.

1:05 rovar: like a peek

1:05 logic_prog: here's the real problem:

1:05 Im wriitng a piece of code in cljs, which takes stuff of a chan and sends it over a websocket

1:05 egosum: ddellacosta: i lied, it doesn't work with named functions, sorry. Yeah I can't get it to work with functions at all…

1:05 logic_prog: so something like (go (loop [msg (<! input-chan)] (. websocket send msg) (recur (<! input-chan))))

1:06 now, when the .websocketd send throws an error

1:06 I'd like to catch it, fire up a new websocket, and send the msg

1:06 thus, I'd like to "push the msg back to the front of the channel"

1:06 does this make sense? am I solving this in the wrong way?

1:06 ddellacosta: egosum: yeah, I was having trouble getting it to load at all, so I was still digging into the code

1:07 egosum: but I'm pretty sure the patterns don't get evaluated, as it seems you want to do

1:08 egosum: see how i extended the pattern emission to sets, though? evaluation is happening there; similary with regexes

1:09 i may just need to dig into the code, or post on SO and hope dnolen will see it :)

1:09 rovar: hmm

1:14 ddellacosta: egosum: right, I see what you're saying

1:14 rovar: egosum: hmm. I'm mucking about with your gist in the repl.. it seems like it should definitely work.. I might try to macroexpand to make sure everything's getting evaluated at the right time..

1:16 egosum: rovar: right, in my super basic debugging, it looks like the #() form is getting expanded to (fn* …) and then match tried to destructure it like an list. Also, if I use a named function, it treats it like a wildcard… so there's that, too.

1:16 Will have to return to it tomorrow. Thanks rovar and ddellacosta for the help

1:16 rovar: egosum: my guess is that it can't determine the type

1:17 not for the multimethod

1:17 I don't think multimethods can switch on functions because it doesn't know exactly what they are

1:17 egosum: eggnoggin: ah interesting

1:17 rovar: ^* oops

1:18 rovar: I thought I remember reading that about multimethods.. but I am not sure

1:18 oh well.. time for sleep

1:18 happy Christmas all

1:19 ddellacosta: oh, you guys both went away. Sad. ;-(

1:19 logic_prog: did you get your core.async thing working?

1:19 logic_prog: ddellacosta: yeah, cljx fucking rules

1:20 also learned about lein pdo

1:20 guess santa delivered twice this year

1:20 ddellacosta: logic_prog: sweet. :-)

1:20 logic_prog: it's aamazing

1:20 how damn simple #+clj and #+cljs are

1:20 it's so "obvious" in retrospect

1:21 ddellacosta: yeah, I had a similar experience the first time I used cljx--I was really impressed by how *simple* it was to use.

1:21 I was kind of skeptical before that.

1:21 bitemyapp: cljx is a lot more obvious if you've done C before - especially on a legacy project.

1:21 logic_prog: ddellacosta: yeah, it's as if someone smart looked at the problem and asked "what is the most fundamental primitive to make this happen" -- rather than someone hack something up, then realize they forgot about Foo + hack something else up + forgot about Bar + hack somethign else up

1:21 bitemyapp: old code in old languages is 50% preprocessing, 50% sanity you're willing to put on the altar.

1:22 10% coworker's sanity you're willing to involuntarily put forth for burning.

1:23 ddellacosta: bitemyapp: you must be talking about macros, huh? I mean the C variety. The last time I wrote C "professionally" was making a printer driver like 14 years ago...

1:24 bitemyapp: macros are a part of it. There's more than that even though.

1:24 ddellacosta: bitemyapp: C scares the crap out of me, honestly...it seems like you really have to invest serious time to get good at it before you run the risk of seriously f'ing things up.

1:24 bitemyapp: pragmas, ifdefs, yadda yadda.

1:24 ddellacosta: writing C is less like programming and more like being a lawyer with a gun to your head.

1:24 a loaded gun. with a faulty trigger.

1:24 ddellacosta: bitemyapp: ah, that shows my ignorance, I thought that all fell under the category of "macros..." but I guess you'd say, "preprocessing directives," huh?

1:24 bitemyapp: haha, scary dude

1:25 bitemyapp: "oh shit, wait " *BLAM*

1:25 bitemyapp: ddellacosta: yes, preprocessing directives.

1:25 my "test all the things!" tendency came from C, not from the newfangled Python/Ruby crap.

1:25 Only knowledge of the C Standard, paranoia, and empiricism can save you.

1:25 ddellacosta: bitemyapp: that makes a whole lot more sense

1:26 bitemyapp: empiricism alone isn't enough because undefined behavior can make things blow up at unexpected times that previously worked on your machine

1:26 ddellacosta: I have a lot of respect for anyone who can write C well though.

1:26 bitemyapp: -Wall -Werror is advisable too.

1:26 to help catch UB.

1:26 ddellacosta: ugh

1:26 andyf: ddellacosta: bitemyapp: Or avoid the corners of the language, and stick with a reasonable subset.

1:27 bitemyapp: ddellacosta: nobody writes C well in the courageous sort of way that I think of as "language comfort". There are people who are merely terrified of the right things to not stray from the golden path very often.

1:28 as much as people to rail on it, it's sometimes (in certain contexts) easier to write valid C++ if you know the right patterns.

1:28 ddellacosta: yeah, well, I'm hanging out in #clojure for a reason...

1:28 bitemyapp: because in C++ there are rules and patterns to resource acquisition you can follow that will generally be okay. You get some help from the compiler WRT types as well.

1:28 but in C? nihilism reigns supreme.

1:28 ddellacosta: haha

1:29 bitemyapp: with you, it always ends up getting philosophical. ;-)

1:29 bitemyapp: void* all the things. Look before you leap? pffft. that's for quiche eaters.

1:29 andyf: C++ has a lot more language-lawyerism to it than C does -- there is just a lot more to it.

1:29 bitemyapp: if you think C++ has a lot more language lawyerism, you haven't spent much time around ##C or C programming in general.

1:29 90% of C is simply not fucking yourself with UB or nonsensical code that seems reasonable on the face of it.

1:30 and knowing which 3/4s of the standard library is hopelessly teacherous.

1:30 the primitives, tooling, and libraries provided in C++ are safer.

1:30 andyf: Unless I'm completely ignorant of the kinds of things that have undefined behavior (I may be), there is a reasonable subset of C that produces predictable behavior.

1:31 bitemyapp: hum, yeah. spend some time writing C and bringing it up in ##C

1:31 your starry-eyed, "but surely C is okay and C++ is not?" will disappear fast.

1:31 andyf: I use C professionally on a regular basis.

1:31 bitemyapp: IME, C++ gives you more brick and mortar to actually scale up and away from petty problems.

1:31 you can't scale up in C without producing bullshit like glib.

1:32 andyf: Or you just don't scale up to the same levels of abstractions

1:32 bitemyapp: right but that's part of the problem.

1:32 andyf: Not if the application doesn't need it.

1:32 bitemyapp: You'll never stop using poisoned toothpicks in C.

1:32 poison-tipped*

1:35 ddellacosta: c'mon guys...don't argue about C in #clojure. Not on Christmas. *sob*

1:35 * ddellacosta ponders making a baby Jesus and C joke, but thinks better of it

1:35 andyf: So on a happier #clojure note, the Eastwood lint tool is coming along nicely, probably ready to release a new improved version in a week or two.

1:36 bitemyapp: ddellacosta: I love FP, but sometimes...just sometimes...an opaque function was not the right choice for the outer layer of an API.

1:36 sometimes data with the "do-er" functions provided besides is better for introspection.

1:36 andyf: this is part of the shift to the new analyzer tooling and the like?

1:37 andyf: yes. Bronsa has improved tools.analyzer(.jvm) quite a bit in the past month.

1:37 ddellacosta: that's pretty cool, I gotta give it a shot

1:38 andyf: I can't say it will turn your life around, but I've heard it has found one case where a clojure.test deftest was not being run (because of duplicate deftest names), and the disabled tests when run pointed out a bug in the project.

1:39 bitemyapp: eastwood and kibit have cleaned stuff up in the past for me, but I think it was mostly kibit doing the clean-up duty before...I think this was before the improvements to eastwood started.

1:39 andyf: Running it right now requires doing 'lein install' on tools.analyzer, tools.analyzer.jvm, and eastwood itself, all latest versions, because there are no released JARs for the first two yet.

1:39 bitemyapp: I decided to take your example and try it in Haskell: Multiple declarations of `blah'

1:39 so uh, denied :)

1:39 SSA ftw?

1:40 andyf: meaning the Haskell compiler disallowed a redefinition?

1:40 yedi: i wanna read some good clojure code to learn some better clj design techniques, anyone have suggestions for repos / projects i should look at?

1:41 bitemyapp: andyf: correct.

1:41 andyf: If so, such a change to Clojure would never happen.

1:41 bitemyapp: GHCi caught it too.

1:42 andyf: Maybe, maybe, an optional warning that was not the default, but even that would be an uphill battle.

1:42 bitemyapp: andyf: if I was to change Clojure it'd end up being Haskell with S-expressions and macros.

1:42 Not exaggerating.

1:43 andyf: IIRC there are 1 or 2 past projects that were some blend of Haskell + a lisp.

1:43 bitemyapp: well I mean there was Chris Done's thing. Lisk.

1:44 andyf: mostly I just don't really care for Haskell's syntax or glyphs - but it doesn't bother me enough to stop by any means.

1:44 everything is an expression.

1:44 andyf: What I'd like to see is some automated way of detecting whether an interesting subset of Clojure functions are pure functions or not.

1:45 i.e. it would say "definitely pure function", "definitely has side effects of type X, Y, Z", or "I can't analyze this".

1:46 bitemyapp: andyf: had core.typed been designed with monads and effect typing in mind that might've been trivial.

1:47 andyf: bitemyapp: Why would core.typed's being designed with monads in mind help it determine whether Clojure functions as they are typically written today are pure or not?

1:48 bitemyapp: because then you could be sufficiently expressive as to say whether a function has side effects or not.

1:48 andyf: you mean, then the language used to specify types in core.typed would be expressive enough?

1:48 bitemyapp: the type system, as it stands, only concerns itself with a subset of what Clojure code actually does.

1:48 andyf: have you written any Haskell?

1:49 andyf: Not anything more than a toy.

1:49 bitemyapp: andyf: I guessed this type signature from memory: http://www.haskell.org/hoogle/?hoogle=Chan+a+-%3E+%5Ba%5D+-%3E+IO+%28%29

1:50 andyf: IO () means it executes for side effects alone and those side effects occur in the IO Monad with a return type of unit.

1:50 andyf: http://www.haskell.org/hoogle/?hoogle=IO+a+-%3E+a

1:51 andyf: http://www.haskell.org/hoogle/?hoogle=ST+s+a+-%3E+IO+a I can see exactly where side effects and mutation occur and what sort of things they're doing at the type level.

1:52 andyf: So if I understand (at least partially), the IO monad would be involved in a correct type of a function that did IO.

1:52 bitemyapp: andyf: strictly speaking, it's only functions that do something that requires binding their operations against the IO monad in order to 'reach' the outside world...but we can go with that approximation if you like.

1:53 >>= in the end is just inversion of control for functional languages.

1:53 andyf: Is there anything in these types to represent things such as set! ing a value, or swap!ing an atom value, or other non-IO things, or do they all fall under IO, too?

1:53 bitemyapp: andyf: gods no.

1:53 andyf: you're getting ST, State, etc.

1:54 andyf: The closest equivalent to a promise or atom in Clojure is an MVar: http://www.haskell.org/hoogle/?hoogle=a+-%3E+IO+%28MVar+a%29

1:54 andyf: there are other kinds of *Vars, and you can see where they're used - in the type signature.

1:54 TEttinger: bitemyapp, be advised: dogecoin is a thing now

1:54 bitemyapp: TEttinger: oh I know.

1:55 andyf: Does effect typing include things that cannot be expressed as a Haskell type?

1:55 bitemyapp: andyf: IO is *not* the only way to know a function is effectful, it's just the default monad for "outside world" stuff.

1:56 andyf: it's technically not just effect typing. Monads and the typeclasses that implement cover a vast superset of what you're thinking of, effects are just one of them.

1:56 andyf: you'd need to give me an example for me to be able to tell you what cannot be expressed as a Haskell type or not.

1:56 dsrx: monads can also be used to model burritos, for example

1:56 bitemyapp: I actually have yet to encounter something that is inexpressible.

1:56 TEttinger: bitemyapp: love

1:56 what is love?

1:58 bitemyapp: andyf: Haskell's type system isn't limitlessly powerful, but only competent Haskell users know where those limits lie. Most of which would be solved by dependently typed langs like Agda and Idris (both participating in the Haskell ecosystem)

1:59 dsrx: e.g. data Burrito m where RollBurrito :: Meat m => m -> Burrito m

1:59 andyf: So here is a maybe-too-trivial question, but if all you cared about was whether a function was pure, or had side effects of type X, or Y, or Z, would you need to become familiar with one or half dozen kinds of monads, or could it be expressed and proved in some other way that doesn't need the concept of a monad?

1:59 bitemyapp: andyf: dependent types can be best summarized (although they reach deeper than that) as types that express constraints on the subset of values the type can represent.

1:59 dsrx: instance Monad Burrito where ...

1:59 bitemyapp: such as, Int having a dependent type, "OnlyEvenIntegers"

1:59 andyf: hum. Monads aren't strictly obligatory, they're just so nice and convenient that they're how you box all this stuff up.

2:00 andyf: hypothetically you could use arrows, but only the psychotic do that.

2:00 unabomber types.

2:00 andyf: generally IO is enough if you care about touching the "outside world"

2:01 andyf: if you care about in-process mutation, it's usually something that is designed to poke at a specific thing like an MVar.

2:01 dsrx: IO functions are pure with an implicit parameter being the state of the world

2:01 bitemyapp: ^^ lol.

2:01 one of those "technically correct...not that helpful" statements.

2:03 andyf: I would guess there is something similar to an MVar, but allows assignment to non-empty locations as well?

2:28 ivan: is a new line with `nil` the idiom for returning nil instead of the last form's evaluation?

2:28 it looks kind of odd

2:28 seancorfield: ivan: nil is just an expression

2:29 ivan: well, of course

2:29 TEttinger: ivan, it seems fine to me

2:29 seancorfield: then maybe I'm not following you?

2:30 ivan: TEttinger: thanks. thought I might have been missing out on some cool way to throw away the return value

2:31 seancorfield: ivan: isn't that up to the caller, to decide what to do with the result?

2:31 ivan: true; in this case giving the caller a Writer to write to a closed file would have been rather mean

2:31 seancorfield: (let [_ (call-something 123)] 42) ;;=> returns 42 but also invokes call-something (and throws away the result)

2:32 apologies if i came in halfway through a conversation :)

2:32 ivan: no, nothing above

2:33 seancorfield: thanks, forgot I could have done that

2:34 seancorfield: or (with-open [r (make-resource :x)] (do-something-to r)) ;;=> closes r but returns result of do-something-to call?

2:40 * ivan reads random websites as fressian data and gets 60

3:14 bitemyapp: ivan: 60?

3:14 ivan: that's a <

3:16 I have been finding jig extremely handy and suggest y'all check it out despite the lack of new announcements on the list

3:16 unless you've already got your own jig, but maybe even then

4:45 logic_prog: am I not allowed to use "recur" inside of a try/catch block?

4:48 ddellacosta: logic_prog: recur has to be in the tail position, and unless you can use a try/catch block as a recursion point, it's doubtful...

4:49 logic_prog: ddellacosta: what does "use a try/catch block as a recursion point" mean?

4:49 my current solution ends up doing something like (let [status (try .... catch ...)] depending on status, figure out how to recur)

4:50 ddellacosta: logic_prog: so, you need to have your recur go back to a recursion point, which is either a loop or function...not sure what else qualifies (looking it up now). And since it has to be the tail position in that, you'll never be able to put it inside a try/catch block...

4:51 logic_prog: ddellacosta: can you point me at the docs you're reading?

4:51 ddellacosta: logic_prog: ah, sure, sorry: http://clojure.org/special_forms#Special%20Forms--(recur%20exprs*)

4:52 logic_prog: what I'm not sure about is what qualifies as a recursion point--maybe let could qualify as well?

4:52 logic_prog: so in short, recur = only where tail recursion would have otherwise worked; recur != goto

4:52 ddellacosta: logic_prog: yeah, that's my understanding.

4:53 logic_prog: I think "if you did a recurisve call here, it would be tail-call-optimized if jvm supported tail-call-optimiation" = "qualifies as 'recur' recursion point"

4:53 the cljs compiler could give slightly more informative compile errors, had to binary search to figure out what line of code was causing thi smess :-)

4:53 ddellacosta: ah.

4:54 logic_prog: btw, out of courisity, given you helped me with crossovers / cljx, what's your occupation? do you use clojure in your daily work?

4:54 ddellacosta: yeah, I was thinking about writing a blog post on more common errors to explain them to newbs (not saying you're a newb, just thinking about the blog post)

4:54 seems like it's a sticking point with a lot of folks

4:54 yeah, I work for a Canadian startup, we do full-stack Clojure

4:54 logic_prog: yeah, someone neds to write a wrapper around the cljs/clj wrappers,

4:54 to regex match the error message and print out a list of 5-10 things you should try to fix it

4:55 ddellacosta: logic_prog: yeah, that kind of thing could be handy

4:55 the thing is, once you get a feel for them they really do seem relatively clear--there are a lot of type errors, or complaints about undefined names and whatnot

4:55 logic_prog: ddellacosta: ah, nice, is this part of the waterloo incubator group? (there's some canadian group taht apaprently has been funneling top talent startups to the valley)

4:55 ddellacosta: logic_prog: huh, I don't think so--but our lead is from Waterloo, so maybe there's a connection?

4:56 logic_prog: yeah, it reminds me the early days of debugging C++ templates

4:56 ddellacosta: I'm an American working remotely, and I don't know all the details on that.

4:56 logic_prog: after a year or so, you stare at the mess and go, of course, I should remove that const

4:56 ddellacosta: yeah. But definitely, it is confusing at first.

4:57 bitemyapp: I had a wonderful dinner tonight. Housemates made pasta, turkey meatballs, and marinara.

4:57 Glass of wine and a brownie dessert too.

4:57 ddellacosta: bitemyapp: nice. :-)

4:57 bitemyapp: Best meal I've had in a long time.

4:57 * bitemyapp sighs happily

4:57 ddellacosta: jealous, just found out my wife won't be home until 9:00 or later. :-(

4:58 thinking I'll do a workout then cook myself a sad Christmas dinner. *sniff8

4:58 logic_prog: I ate frozen left overs + listened to talks by Musk, Khosla, and Draper. I win christmas eve right?

4:59 ddellacosta: logic_prog: haha...sure. :-)

4:59 logic_prog: where are you, btw.?

4:59 logic_prog: silicon valley

4:59 you?

4:59 clojurebot: you are likely to be eaten by a grue.

4:59 ddellacosta: ssh, clojurebot

4:59 logic_prog: I'm in Tokyo

4:59 bitemyapp, logic_prog: what time is it for you guys?

4:59 bitemyapp: logic_prog: hello fellow SV-ite.

4:59 logic_prog: 1:58am

4:59 bitemyapp: ddellacosta: 0158

4:59 ddellacosta: 2 AM ish,

5:00 logic_prog: holy shit, our clocks are synched

5:00 ddellacosta: just realized how easy it was to look it up myself...

5:00 logic_prog: bitemyapp: what startup do you work at?

5:00 ddellacosta: I suppose you are probably using the same ntp server?

5:00 bitemyapp: logic_prog: genetics company in SOMA - InVitae.

5:00 ddellacosta: mos' likely.

5:01 ddellacosta: well, I'm going to take my leave for the time being, do a workout and then consider how I can roast up some chicken thighs...

5:01 arcatan: the same ntp server network

5:01 logic_prog: bitemyapp: crunchbase says you guys know how to fund raise

5:01 bitemyapp: logic_prog: yeah our executive team is baller.

5:02 logic_prog: ddellacosta: thanks again for help pointing out the recur issue

5:02 ddellacosta: logic_prog: sure, glad I could help! Cheers. ;-)

5:02 bitemyapp: logic_prog: what company are you at?

5:03 logic_prog: i'm a grad student

5:03 bitemyapp: logic_prog: what school and what subject?

5:03 logic_prog: *shakes fist* @ startups raising the local rent

5:04 bitemyapp: logic_prog: pffft, I'm figuring out how soon I can leave the Yay Area - partly because of the rent.

5:04 logic_prog: I think ti's this vicisou cycle

5:04 where all cs people are forced to do startups to pay rent

5:04 which in turn raises the rent

5:05 bitemyapp: Startups are not a good way to pay the rent.

5:05 logic_prog: what school and field are you in as a grad student?

5:05 logic_prog: Stanford/CS

5:05 bitemyapp: well that's borderline typical.

5:05 logic_prog: MS or PhD?

5:05 logic_prog: what is borderline typical?

5:07 bitemyapp: you're a bay area resident in #clojure - if not a working programmer, a person doing CS at Stanford seems approriate but not my first guess.

5:09 logic_prog: yeah, statistically, there's also that other school

5:09 TEttinger: san gabriel valley resident, no degree... I just like clojure

5:09 logic_prog: Berkeley or something

5:09 bitemyapp: logic_prog: fuck those hippies.

5:09 logic_prog: actually, I tihnk a significant # of stanford faculty are from berkeley, ...

5:10 TEttinger: how can you tell, they smell like weed?

5:10 bitemyapp: I reiterate what I said a moment ago.

5:11 logic_prog: okay, finall killed this bug

5:11 now let's see if code runs

5:11 TEttinger: killed it alive

5:14 logic_prog: worked :-)

5:34 cYmen: Good morning crowd and merry christmas!

5:37 After adding a dependency to my project.clj what do I have to do to make my repl aware of it?

5:37 logic_prog: restart the repl

5:40 is node.js significantly more lightweight than jvm ?

5:41 cYmen: Damn, I hate doing that. The errors are always so opaque.

5:41 logic_prog: i'm considering having server side also run on node.js since jvm is q bit heavy

5:41 cYmen: Wait, how do I restart the repl?

5:42 C-x k, right?

5:46 kilon: merry christmass :)

5:47 cYmen: Meh, it hangs at "connecting to nrepl on localhost:port"...any ideas what that means?

5:47 nones: what right way to convert `[Ljava.lang.String;` to clojure vector

5:48 cYmen: nones: Not sure what you want to do but you can just use it as a sequence so you probably don't have to.

5:50 arcatan: cYmen: maybe try to start the repl from the command line and see if there are helpful error messages? cd your-project; lein repl

5:50 TEttinger: ,(let [^"[Ljava.lang.String" s "whee"] (vec s))

5:51 clojurebot: [\w \h \e \e]

5:55 arcatan: ,(vec (into-array String ["a" "b" "c"]))

5:55 clojurebot: ["a" "b" "c"]

5:58 cYmen: arcatan: That's what I usually do

8:16 tzach_: ,"test clojure bot"

8:16 clojurebot: "test clojure bot"

8:18 troezen: cYmen: isn't that what alembic is for? https://github.com/pallet/alembic

8:18 haven't used it myself though

8:58 pandeiro: anyone know what needs to go in the http_proxy environment variable to access repos when behind a proxy? i tried http_proxy= my external IP and that failed...

9:28 rovar_away: pandeiro: http_proxy=http://my_proxy:3128

9:29 pandeiro: or whatever is the address and port of your proxy

9:31 pandeiro: rovar_away: yeah unfortunately i'm behind a hotel wifi proxy, and no combination i've tried has allowed me to access private repos :(

9:33 rovar_away: pandeiro: usually they're just a wall that you have to click through with your browser, then all http/s works..

9:33 dunno

9:33 pandeiro: rovar_away: yeah, that is what is happening... EXCEPT for with lein

9:34 i'm getting 403 Forbidden's back from S3... no idea really, I just saw the message about http_proxy from lein and thought that might be it. Maybe something else entirely.

9:34 Thanks for the help.

9:41 rovar_away: could be the hotel, most likely its the perms on the s3 repo not allowing public access..

10:26 Morgawr: merry christmas clojurians

10:29 ,(str (apply str (reverse "samtsirhc yrrem")) " " (reduce str (take 5 (repeat "ho! "))))

10:29 clojurebot: "merry christmas ho! ho! ho! ho! ho! "

10:29 Morgawr: :)

10:47 cYmen: ,"merry christmas!"

10:47 clojurebot: "merry christmas!"

10:47 cYmen: look mine's a quine! :)

10:51 rovar_away: now write a clojurebot that writes more clojurebots

10:51 one word: skynet

11:36 Borland_Islaam: AimHere, hey sweetie

12:22 arrdem: Merry christmass folks!

12:26 grandy_: hello, i'm curious what the best way to do the following in clojure would be --- i want to read two csv files, "join" them, and output a new one

12:27 seancorfield: grandy_: how big are they?

12:27 ,(doc slurp)

12:27 clojurebot: "([f & opts]); Opens a reader on f and reads all its contents, returning a string. See clojure.java.io/reader for a complete list of supported arguments."

12:27 seancorfield: ,(doc spit)

12:27 clojurebot: "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer."

12:28 seancorfield: otherwise you'll need to read/write the first one and then read/append the second one using more low-level Java file I/O stuff

12:29 but (spit "out.csv" (str (slurp "in1.csv") (slurp "in2.csv"))) might be sufficient

12:29 kirrean: is there a way to attach messages to failing :pre/:post like you can with (assert false "oh no!")?

12:30 grandy_: seancorfield: a few thosand rows each, ,not big

12:30 clojurebot: It's greek to me.

12:31 grandy_: seancorfield: thanks

13:19 devn: Happy Day Off Day

13:23 edw: My day off is an opportunity to read the GNU Emacs Lisp Reference Manual cover to virtual cover.

15:26 davidbe: I've a strange error with selmer. https://www.refheap.com/22225 {{profile}} is what I'm passing through and contains address-information. The first two lines of the paste are for testing and work well. I get "street + number" and "zip-code + city".

15:27 But when passing {{profile.street}} and {{profile.city}} to input, it doesn't pass behond space. So what works in the first two lines, get wrong there. e.g. instead of "Wetstraat 16", I get "Westraat"; and "1000 Brussel" becomes "1000" in <input>

15:44 rovar_away: david118: enclose your {{...}} in ""

15:44 when its in html

15:44 davidbe: enclose your {{...}} in ""

15:45 davidbe: rovar_away: that helped

15:45 rovar_away: thanks alot!

15:47 mrhanky: total beginner here. how can i access a method from a ns without specifying it's ns? i'll do (:require [ns.sub]), in ns.sub i have a method "test". i want to access test via (test) and not (ns.sub/test)

15:53 arcatan: (:require [[ns.sub :refer [test]])

15:54 or if you want to refer to all the variables in ns.sub, :refer :all

16:06 mrhanky: thanks arcatan, forgot to mention i'm on clojurescript right now, this wont work as expected

16:08 anyway, i did some ugly defn, this will work for now

17:02 devn: I have a map def'd: (def fn-map {:a #(.foo %1 %2), :b #(.bar %1 %2) ...}). I get reflection warnings on all of these because I don't have an annotation on %1. Is there any way to annotate those all programatically, rather than do #(.qux ^BlahBlahBlah %1 %2) a bunch of times?

17:14 justin_smith: you could make a macro that creates an anonymous function with the right annotation, if they have a predictable structure especially

17:38 arrdem: arcatan: did nobody answer you?

17:38 oops. arcatan got it taken care of.

17:45 logic_prog: anyone know of a good library for combining some type of crawling (say net.cgrand.enlive-html or org.httpkit.client) together with core.async ? I want something where (1) there is this channel, where I send it urls, and (2) there's this thread pool of some sort that grabs the urls in parallel, and (3) pushes the contents back onto the core.async channel

18:14 bitemyapp: logic_prog: httpkit async + callbacks -> core.async channel

18:14 logic_prog: bitemyapp: who manages the thread pool in the above example?

18:15 oh wait, is there no thread pool since httpkit wgets are async?

18:16 bitemyapp: logic_prog: iunno. read the code.

18:58 fredyr_: for the clojurescript+react/om interested, i posted a blob post earlier today http://www.lexicallyscoped.com/2013/12/25/slice-of-reactjs-and-cljs.html

19:48 Mandar: is there a way to bind a symbol conditionnally?

19:48 something like (let [x :a if something, x :b if something else] x)

19:49 i know i can use a function call to do this

19:49 but i'm wondering if there's any other way

19:50 (let [x (my-fun)] x) obviously works

19:53 TEttinger: Mandar, if-let ?

19:54 (doc if-let)

19:54 clojurebot: "([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"

19:54 Mandar: if-let only works if if want to bind the var used in the test, doesn't it?

19:55 TEttinger: correct...

19:55 the simplest way I can think of is

19:55 Mandar: let's say i want to do some work with a seq, but filter the seq first if i have a specific parameter (a filter function) given to my function as an arg

19:56 TEttinger: &(let [x (if true :a :b)] x)

19:56 lazybot: ⇒ :a

19:56 Mandar: oh yes

19:56 that's awesome thank you!

19:56 TEttinger: heh, you almost had it!

19:56 no prob

19:59 Mandar: would have never found it

19:59 i'm not used to (if) being something returning a value

20:16 logic_prog_: ibdknox: why does lighttable use node.js instread of jvm on the server side?

20:25 Mandar: logic_prog_ he explains it a bit here http://www.youtube.com/watch?v=V1Eu9vZaDYw&t=19m58s

20:26 basically, he's using chrome and css instead of coding all the user interface server-side

21:17 bitemyapp: in what universe is lighttable server-side?

21:17 it's a client application.

21:17 also harnessing the browser + clojurescript was a really good idea on his part - JVM is slow for client-apps :(

21:24 arrdem: bitemyapp: yo you had a database you were suggesting as an alternative to Mongo. What was it?

21:34 bitemyapp: arrdem: RethinkDB.

21:34 arrdem: you need schema-free right?

21:38 Mandar: (having a server-side IDE i mean)

21:39 bitemyapp: Mandar: best example of that is FPComplete.

21:39 Mandar: bitemyapp, looks nice!

21:41 bitemyapp: Mandar: it seems pretty well designed. Backend is Haskell, frontend is JS compiled from Fay (Haskell). I don't use it because I'm an Emacs user, but I recommend it to people that need something shake-n-bake.

21:42 Mandar: when i'm trapped with clients who want me to work from their computers, i often ssh to a remote server just to have vim

21:42 arrdem: bitemyapp: not really.. I may in fact bust out an embedded SQL. Really I'm just building a price time series.

21:43 bitemyapp: yeah rethinkdb was the name I was searching for tho. thanks.

21:44 bitemyapp: arrdem: if you use RethinkDB, you should try Revise :)

21:47 arrdem: bitemyapp: hehe bias not withstanding I'll check it out.

21:49 I may just use an EDN serialized file for a while tho... we'll see.

21:52 bitemyapp: arrdem: files are for plebs, but okay :)

21:53 arrdem: bitemyapp: hey now, I'm a Plan 9er. watch yoself.

21:54 bitemyapp: Plan 9ers are also the ones responsible for Go, so they're in my "burn" pile.

21:55 Mandar: bitemyapp, heh, why do you hate go? :)

21:55 arrdem: I'll take no credit for Go, but IMHO standardizing on the filesystem as the general system interface is a good thing

21:55 procfiles and devfiles you have the 9ers to thank for.

21:59 bitemyapp: arrdem: and I'm fine with that.

22:00 arrdem: but the parsimonious and primitive mindset that improved one thing, ruined another (prog langs)

22:00 Mandar: "How do we make something less versatile and powerful than C, with an equally pointless type system, but less expressive than almost every other language too?"

22:02 Mandar: bitemyapp, gc + fast compile time maybe?

22:02 but i don't think it's trying to be a competitor to c

22:03 hyPiRion: Well, the authors said it was for replacing their C and C++ use, so I'm pretty sure it is.

22:03 andrei: Why does clojure want to box up my loop argument? (fn [] (loop [i 0] (if true 0 (recur (+ i 0)))))

22:03 Mandar: hyPiRion, oh

22:03 andrei: recur arg for primitive local: i is not matching primitive, had: Object, needed: long

22:05 ddellacosta: andrei: that is bizarre, and I just get 0 each time anyways...not sure what is up

22:06 andrei: not sure how that would increment at all, honestly

22:07 bitemyapp: ddellacosta: Spent this Christmas with my loved ones this year again - myself.

22:07 * bitemyapp toasts his cup of pu-ehr tea in ddellacosta's direction

22:07 ddellacosta: I'm writing some tests, and I'm mocking out some (mutative) functions using with-redefs, then testing the arguments that get passed into a function inside. Don't like it--anyone have any other approaches?

22:07 * ddellacosta toasts back with his morning coffee.

22:08 Mandar: good night

22:08 ddellacosta: bitemyapp: I hope you had a good time regardless. At least you know I'll be working and around, so you can always ping me!

22:08 * arrdem will abstain from the 9pm coffee crew

22:08 bitemyapp: ddellacosta: your morning is about when I usually start coding (1906 here)

22:08 ddellacosta: Mandar: 'night

22:08 arrdem: heh, it's noon for me

22:08 arrdem: bitemyapp: your clock is good. god bless ntpd.

22:08 bitemyapp: ddellacosta: I talked to my parents on the phone today and yesterday. Good enough for me - for now. I do need to leave the bay area, get some land and dog though.

22:09 ddellacosta: bitemyapp: my wife and I spent most of our Christmas evening looking at videos of frolicking Shiba Inus in Hokkaido snow...looked very very nice. We would like a dog and land too, so I know exactly where you're coming from. That plus fast internet and I'm good, I think...

22:10 bitemyapp: ddellacosta: that sounds delightful <3

22:11 ddellacosta: bitemyapp: doesn't it?

22:11 if I do say so myself

22:11 bitemyapp: ddellacosta: I like big dogs. Rottie/Pit bull and larger.

22:11 english mastiff, if I had my way.

22:12 ddellacosta: bitemyapp: I am a labrador kinda guy myself. But recently started liking (very selectively) some smaller dogs

22:12 justin_smith: I never got the point of tiny dogs until I moved to the city

22:13 bitemyapp: you can own certain breeds of large dog in the city.

22:13 Primarily great danes.

22:13 justin_smith: right, but they can be hell on an apartment (and miserable in a small one)

22:13 ddellacosta: yeah, exactly--here in Tokyo you occasionally see folks with great danes, and the mind boggles

22:14 bitemyapp: justin_smith: great danes? Not particularly compared to most large breeds.

22:14 justin_smith: a french bulldog can actually get exercise by running circles around an apartment, a german shepherd would break things doing the same

22:14 bitemyapp: justin_smith: great danes are very chill and low maintenance.

22:14 justin_smith: hum, GSDs are high energy working dogs, great danes are not.

22:14 justin_smith: so not a high energy breed, OK

22:14 bitemyapp: it's not the size, it's the breed and what they were designed for.

22:14 ddellacosta: good point, probably really depends on the breed...

22:14 justin_smith: yeah, I have had a shepherd, never had a dane

22:14 bitemyapp: great danes are couch thieves, that's about all they do.

22:14 justin_smith: gotcha

22:14 ddellacosta: but still, a big dog in a small apartment it just...takes up so much space.

22:14 bitemyapp: so as long as you can shove the massive bastards over, they're fine in an apartment.

22:15 ddellacosta: heh

22:15 andrei: ddellacosta: What the loop does doesn't matter

22:15 bitemyapp: ddellacosta: I think you could manage a single great dane in a studio, honestly.

22:15 ddellacosta: andrei: okay, well, I'm not seeing the boxing you are

22:15 andrei: ddellacosta: Do you have the appropriate warnings enabled?

22:16 ddellacosta: andrei: ...no I guess not...?

22:16 bitemyapp: yeah, but unfortunately we can't have *any* dogs here. :-(

22:16 bitemyapp: or pets in general. I'd be happy with a cat too.

22:16 bitemyapp: ddellacosta: I like cats, but I have a chunk of my psyche devoted to dogs.

22:17 not having a dog is like missing a limb.

22:17 ddellacosta: andrei left

22:17 TEttinger: so I have some variables I'd like to just spit into a file. the problem is, some are atoms, of maps, containing primitive arrays.

22:17 ddellacosta: what warnings was he talking about? I was just searching around and couldn't figure it out

22:18 TEttinger: pr-str won't produce re-read-string-able output with arrays, is there an alternative way where I could convert these things to vectors and deref atoms?

22:19 justin_smith: ddellacosta: there is a primitives lib that gives warning when numbers get boxed

22:20 ddellacosta: though code like he had should get fully unboxed by clojure

22:20 https://github.com/ztellman/primitive-math

22:20 ddellacosta: justin_smith: huh, okay...I was very confused by his issue

22:20 justin_smith: his loop was clearly faked up (if true) and all

22:21 ddellacosta: yeah, good point...something weird was going on there

22:22 justin_smith: the compiler should have seen that i could only be an int (unless it got boxed because it could have gotten promoted / overflowed?)

22:22 TEttinger: I think literals default to boxed in recent clojure versions, but I can't be sure

22:23 ddellacosta: yeah, I have no idea...I've never ever seen anything like that in Clojure, but I've only been using since 1.3

22:23 TEttinger: and it would be Long

22:23 justin_smith: TEttinger: I left my copy of "high performance clojure programming" at work, but iirc the clojure compiler unboxes when it can statically know the arg types

22:24 and yeah, without a declaration it would default to a long / Long of course

22:25 TEttinger: so any ideas on how to modify the behavior of pr-str to vec any arrays before printing?

22:27 justin_smith: I think you need to define print-dup / print-method for the type

22:27 allenj12: hey i wanted to make a machine learning library for myself for kaggle competitions. but i am having trouble finding a good linear algebra library, i tried using vectorz-clj but it seems to be impossible just to be up and running. are there any better librarys or should i roll my o

22:27 own

22:27 justin_smith: TEttinger: yeah, there is a print-dup multi-method you can define

22:27 that is what pr-str ultimately calls in most cases

22:27 arrdem: allenj12: roll your own on top of core.matrix

22:27 bitemyapp: ddellacosta: do you like to read?

22:28 ddellacosta: bitemyapp: yeah, although lately mostly random scifi and compsci books

22:28 justin_smith: TEttinger: if the *print-dup* dynamic var is false, then the print-method multimethod is called instead, same deal, define a dispatcher for the multimethod

22:28 ddellacosta: bitemyapp: why do you ask?

22:28 bitemyapp: ddellacosta: I "I learned years ago never to argue with a specialist; you can't win. But I also learned that the history of progress is a long, long list of specialists who were dead wrong when they were most certain."

22:28 allenj12: arrdem: kk seems sad we dont have a ready library yet since clojure seems so great for machine learning

22:28 bitemyapp: woops, wrong pasta.

22:29 ddellacosta: bitemyapp: haha, good quote though...

22:29 bitemyapp: ddellacosta: I really enjoyed this: http://hpmor.com/

22:29 when I first read it, I was enthralled.

22:29 ddellacosta: it does help if you've read the original Harry Potter series though.

22:30 TEttinger: wizard people dear readers

22:30 ddellacosta: bitemyapp: ah, haha...sounds fun. Not a big Harry Potter fan, but I know I'm not a big fan as I've read all of them...swearing the whole way through.

22:30 justin_smith: TEttinger: I saw him do that live

22:30 fucking hilarious

22:31 TEttinger: heh it's on youtube now https://www.youtube.com/watch?v=xjYPfOnuf9w

22:31 arrdem: allenj12: yeah... the real issue is that clojure's numeric operations are for the most part strictly slower than Java's due to immutability constraints so people tend to just roll wrappers around Java ML toolkits.

22:33 allenj12: math.matrix is a step in the direction of aknowledging that and mitigating it by making it easy for wrapped (fast) matrix representations to behave like a naive Clojure vector of vectors

22:33 bitemyapp: ddellacosta: hum. hpmor has an appeal above and beyond harry potter though.

22:33 ddellacosta: the rationalist spin on it is fascinating and massively entertaining (for me)

22:33 ddellacosta: bitemyapp: oh, it looks like it does, which is why I'm interested in taking a look.

22:34 bitemyapp: ddellacosta: it was one of those rare bits of reading where it absolutely hooked me.

22:34 ddellacosta: last thing to hook me like that was game of thrones and the mistborn series.

22:34 ddellacosta: bitemyapp: what's mistborn?

22:34 bitemyapp: ddellacosta: Brandon Sanderson fantasy trilogy. Very very well done.

22:35 ddellacosta: bitemyapp: cool, will check it out. Unfortunately, my reading list is...quite long.

22:36 allenj12: arrdem; interesting.. well looks like im off righting my own. hopefully it wont be too long tho till something just works for atleast simple operations.

22:36 justin_smith: I've been reading Murakami's "Hard Boiled Wonderland and the End of the WOrld" and it gives me the weirdest programming related dreams

22:37 like cyberpunk meets alice in wonderland

22:38 TEttinger: justin_smith, uh... do you have any docs on the print-dup stuff? I don't think I've ever used multimethods yet

22:38 justin_smith: http://clojuredocs.org/clojure_core/clojure.core/print-dup

22:39 a multimethod is a dispatch function plus an implementation for each match

22:39 that doc shows how to extend to a new dispatch result

22:40 print-dup is the simple kind of multimethod, it just dispatches on the class of the arg

22:40 TEttinger: right, but arrays aren't classes... right?

22:41 justin_smith: arrays have a class

22:41 TEttinger: maybe i could detect the type like "[D"

22:41 justin_smith: its just that their contents are not boxed objects

22:41 yeah, that is actually a class

22:43 ,(= (class (double-array [1.0 2.0 3.0])) (Class/forName "[D"))

22:43 clojurebot: true

22:44 justin_smith: it's a class called [D

22:45 clojure has problems with using that class directly, for obvious reasons

22:49 TEttinger: would doubles work?

22:50 justin_smith: (Class/forName "[D") returns the correct class for the dispatch declaration

22:50 or does that not work?

22:50 doubles is not a class, but a function

22:51 an inline function that does a cast at compile time

22:52 the class [D has a name that can't be referenced the way other classes can, because the clojure reader hates it

22:52 TEttinger: ok, it works now

22:52 thanks a bunch

22:52 justin_smith: cool!

22:53 was Class/forName sufficient then?

22:53 TEttinger: I do:

22:53 (defmethod print-dup (Class/forName "[D") [a out] (.write out (str "#=" `(double-array ~(vec a)))))

22:53 and now it does work, I can pr-str and read-string

22:54 (binding [*print-dup* true] (read-string (pr-str (prepare-some-array))))

22:55 that seems to work just fine when used like that

22:55 justin_smith: nice

22:57 now that "#=" in the examples finally makes sense - it is constructing the reader macro

22:57 cool

23:36 proteneer: this may be a dumb as hell question - is there an alternative "compiler" that targets C or Python? There was something like clojure-py from a year ago on github but it seems to have died

23:37 any thoughts on clojurec?

23:42 justin_smith: there is a python targeting compiler, I don't know how mature it is or what the use case is for really wanting it

23:43 bitemyapp: proteneer: I use clojure-py for some stuff.

23:43 proteneer: is it worth it?

23:43 (granted I've always wanted to learn FP for some projects, but we develop exclusively in C/C++/Python)

23:44 bitemyapp: proteneer: if you're trying to learn FP, use the language as it was intended.

23:44 proteneer: specifically if you want to learn FP, use Clojure on the JVM and Haskell with GHC.

23:44 proteneer: hm interesting

23:44 ok

23:45 though my boss will probably kill me if I try to develop a web framework using Haskell

23:45 bitemyapp: proteneer: "alternative" environments are for people that know what they're doing.

23:45 proteneer: I don't see why, but for that matter, I'm not sure why you'd need to make your own web framework.

23:45 proteneer: well just for fun :P

23:45 right now i'm using tornado

23:46 but I'm sort of in the state where I need an excuse to learn a new language

23:46 (FP language being one)

23:46 bitemyapp: proteneer: vanilla Ring+Compojure in Clojure and WAI + Scotty in Haskell is my typical recommendation.

23:48 proteneer: rofl: beam <- param "word"

23:49 bitemyapp: proteneer: structurally, Ring in Clojure and WAI in Haskell are similar.

23:49 both involve the use of function composition to "build up" web applications.

23:49 they also both act as an interface to specific server implementations.

23:51 yedi: so i have an app that takes text files and does some analysis on it and returns clojure data / edn

23:51 the analysis takes a while to do, so i'd like to store/cache both the text and the edn result of the analysis

23:52 arrdem: $google clojure core memoize

23:52 lazybot: [clojure/core.memoize · GitHub] https://github.com/clojure/core.memoize

23:52 arrdem: next!

23:52 yedi: i'd like to keep the data persisted though

23:53 arrdem: yedi: this is a repeatedly booted application?

23:53 yedi: i don't think it would be

23:53 using a db / text files, and i was wondering if there were simple nosql dbs for edn or if i should just use tedt files

23:54 i'd like to be able to keep track of the files that have been analyzed so i wouldn't want the data to dissapear if the app goes down

23:56 are there any really simple edn datastores that don't cost money (like datomic)? if not i'll just use text files i guess

23:56 justin_smith: yedi: one option is to write a simple and complete input-file -> output-file transform, and for each one you are going to analyze, check for existing output file

23:56 bitemyapp: yedi: Datomic doesn't cost money :|

23:56 justin_smith: by simple and complete I mean trivially derived from input, and not conflicting

23:56 bitemyapp: yedi: if simple files can suffice, then so can Datomic Free or Pro Starter.

23:56 arrdem: yedi: yeah I agree with justin_smith here. odds are you'll wind up rolling a custom once-off

23:57 yedi: ill check out datomic free, otherwise i'll prolly just go with justin_smith's suggestion

23:57 thanks

Logging service provided by n01se.net