#clojure log - Dec 10 2013

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

0:06 bitemyapp: fakedrake: fold is usually what you want.

0:07 sritchie: how far is far?

0:07 sritchie: I'm faux-ffended you didn't ask me first.

0:07 sritchie: haha, you're the oracle, man

0:08 I wanted to give the others a chance

0:08 what's the word on logging, sir

0:08 tolitius: sritchie: http://blog.datomic.com/2013/11/datomic-pro-starter-edition.html it does say what your limit is: no • High Availability transactor support

0:08 • Integrated memcached

0:08 • Running more than 3 processes (2 peers + transactor)

0:09 sritchie: but you have everything else

0:09 sritchie: gotcha

0:09 bitemyapp: sritchie: logging what?

0:09 sritchie: bitemyapp: or did you mean, I should have asked about datomic

0:09 bitemyapp: right, but I wrote some stuff for logging too.

0:10 I just need context.

0:10 I reacted to the mention of Datomic

0:10 sritchie: okay, one sec, wrapping up a quick phone thing - but I have logging questions

0:10 fundamental questions

0:11 bitemyapp: I can do fundamental, unless you mean log4j internals.

0:11 cljr: Hmm, alright, i have this string "221ea102", what is the clojure way to convert it to 0x221ea102?

0:11 bitemyapp: cljr: the byte value or the string?

0:11 cljr: well, i'd like to go directly form the string to the byet value

0:12 "221ea102" -? 0x221ea102

0:12 ->

0:12 bitemyapp: cljr: http://stackoverflow.com/questions/11194513/convert-hex-string-to-int

0:12 I googled, Java hex value from string

0:12 t'was the third result.

0:12 sritchie: bitemyapp: haha, no, please keep me away

0:13 bitemyapp: so I'm working on getting my app properly monitored with riemann. I'm writing a little stats-d like interface, with a gauge, counter, etc

0:13 bitemyapp: that's metrics.

0:13 sritchie: yes

0:13 bitemyapp: so logging.

0:13 sritchie: I'm also using timbre for logging

0:13 bitemyapp: timbre has some limitations, but I manage okay with it.

0:13 sritchie: and right now, I'm just logging exceptions, some text strings and maps on certain events,

0:14 bitemyapp: I've been trying to convince pt-toomanyfuckingvowels-nis to make the closure-based interface a part of stable.

0:14 sritchie: haha

0:14 bitemyapp: instead of a global singleton config.

0:14 sritchie: but I'm looking at their appender interface and wondering how I should be thinking about 1) what I'm logging, 2) what structural constraints I should put on the data structures I log,

0:14 cljr: bitemyapp: sorry, did a sorry job of doing my due diligence...wasnt sure what you call 0x... wasnt sure where to start

0:14 sritchie: and where the hell to send the logs

0:14 bitemyapp: yeah, that needs to go away

0:14 the singleton.

0:14 bitemyapp: sritchie: that's why I bugged him about a closure-based interface.

0:14 it was driving me fuckin' batty.

0:14 sritchie: bitemyapp: clearly monitoring and logging are very related

0:14 bitemyapp: cljr: I just google the questions people ask and paste the most plausible answers in channel.

0:15 sritchie: :)

0:15 bitemyapp: cljr: I've been doing it for over a decade. I'm getting good at googling peoples' problems.

0:15 sritchie: I mean, you've worked at much larger companies than I have. surely you have a better imagination for how far to take this line of thinking than I do

0:15 sritchie: eventually you end up with something like kafka or scribe for unifying all "events", logging or otherwise, but I imagine you want to 80/20 this yes?

0:15 sritchie: bitemyapp: haha, I could go all twitter and log absolutely everything

0:16 bitemyapp: every interaction, every function call, all of that

0:16 bitemyapp: that's what I was imagining, but let me describe what I do.

0:16 I do log-level defined granularity, deployment mode defined appenders

0:16 sritchie: yes. I'm looking for the middle ground, after the intensity that I was part of

0:16 bitemyapp: dev == stderr, prod == files + search engine appender

0:17 so you can tail -f/grep if you want, but there's also a unified search engine for log lines, ideally in JSON format -> ElasticSearch.

0:17 if you don't have a complicated deployment, just use a file appender and rsync the files to a central location.

0:17 logrotate'd

0:17 namespaced by machine.

0:17 cljr: bitemyapp: sounds like an unprofitable startup idea

0:17 bitemyapp: then have cron jobs/scripts scan the logs for weird stuff.

0:17 cljr: :_)

0:18 sritchie: bitemyapp: and you're taking care to do log in some structured way, of course

0:18 bitemyapp: sritchie: JSON with some specified/standard fields.

0:18 sritchie: I'd kill for an edn plugin for ES.

0:18 *kill*

0:18 yes yes, I know I can write it myself. I don't have time. I'm working on Simonides, Grom, and Keensweep.

0:18 sritchie: :)

0:18 bitemyapp: and I have a day job.

0:18 sritchie: so, I could do this by sending everything to riemann,

0:18 bitemyapp: and I help people in IRC too apparently.

0:19 sritchie: but do you want ephemeral event triggers?

0:19 sritchie: having it go edn -> json, (technically protobuf -> edn -> json, but whatever),

0:19 and hit elasticsearch

0:19 bitemyapp: I use logging for the history, not for the metrics.

0:19 oh you'd spout from riemann to ES?

0:19 sritchie: yeah

0:19 bitemyapp: nice idea.

0:19 better than mine.

0:20 sritchie: OR I use timbre as my top level abstraction, and give timbre a riemann appender

0:20 bitemyapp: also I really do not like that the Seqable API is a ghetto fmap.

0:20 want my damn <$>

0:20 sritchie: bitemyapp: yes, the type classes do clarify alot

0:20 remember clojure.contrib.accumulator?

0:20 bitemyapp: sritchie: that's what I thought you meant @ riemann appender.

0:20 sritchie: t'was plural, and yes.

0:20 sritchie: bitemyapp: all of these blocks are useful, and I can stack them in so many ways

0:21 bitemyapp: I didn't know people still used that.

0:21 sritchie: bitemyapp: I'm crippled by choices. I can go recreate what I know, but I want to make sure I'm doing it for the right reasons

0:21 bitemyapp: they're not, but it's a janky monoid + semigroup impl

0:21 bitemyapp: Isn't the accumulators library mappend + identity?

0:21 yeah, I figured.

0:21 I still don't know when I would elide identity to make a semigroup in code.

0:22 I guess when identity literally has no meaning for the data type?

0:22 I'd have to dig to make up an example like that.

0:22 sritchie: well, what does "recreate what I know" mean?

0:22 sritchie: because my impression of Twitter's logging infrastructure was that it was a lot more complicated and crossed machine barriers for tracing.

0:22 so that you could follow execution path across the SOA.

0:23 sritchie: bitemyapp: log every API and database interaction in some schemified way

0:23 plus timing data for everything,

0:23 and run everything through riemann, which forwards on to graphite and elasticsearch

0:23 bitemyapp: sritchie: textual queries can carry you a long way.

0:23 sritchie: I'd say you can YAGNI a lot of this stuff initially and add a more sophisticated appender if you find you need it.

0:24 sritchie: bitemyapp: it sounds like I can do the "appender" thing at a few different levels, and they're all equivalent

0:24 bitemyapp: mostly.

0:24 sritchie: at riemann's level, at timbre's level, all of that

0:24 bitemyapp: the error/exception logging is a privileged faculty in Timbre, the rest is par.

0:24 his macro-ified log-level API is fucking insane

0:24 sritchie: haha

0:24 bitemyapp: I've never seen hash-table-of-functions dispatch made so complicated.

0:24 I'd have an easier time understanding an array of function pointers in C>

0:25 sritchie: the profiling stuff looks useful, but pushing that into my code is not the True Way

0:25 bitemyapp: so my homework is to go get an elasticsearch box up on EC2?

0:25 bitemyapp: sritchie: nah, if I needed profiling I'd make it an optional configuration-activated AOP faculty.

0:25 sritchie: uhhh, I'm saying you can avoid this work via YAGNI and stick with vanilla log-lines for now.

0:25 unless you really want structured logging + search, then yes, ElasticSearch.

0:25 sritchie: and just grep them

0:26 bitemyapp: sritchie: ElasticSearch is in general an open source secret weapon.

0:26 knowing it makes your data very discoverable and it scales nicely.

0:26 and just grep them, yes.

0:26 learn ES for the overall leverage it offers, not for this particular problem.

0:26 I'd wait for the "pain" of the absence of structured logging to hit you before adding it.

0:26 sritchie: I want to be the most idiotically technologically advanced race management platform ever

0:27 which we already are, since everything sucks :)

0:27 CRDTs for race timing stopwatch resolution

0:27 bitemyapp: :|

0:27 sritchie: everything, to the extreme

0:27 bitemyapp: this is like the mumble project.

0:27 way ahead of its time.

0:28 sritchie: well, keep in mind, I'm using a startup-oriented cost function for your time.

0:28 sritchie: so I'm assuming it isn't that valuable for the product itself to have structured logging yet.

0:28 sritchie: yes, you're right

0:28 it's valuable to have good monitoring in place

0:28 bitemyapp: sritchie: also if you need user behavior analytics ping me, that's what Simonides is for.

0:28 it's "collect everything, query later" analytics.

0:29 no manual JS event emitters.

0:31 I love it when peoples' cmake setups just work.

0:32 sritchie: bitemyapp: yeah, I don't want to waste time building infra I don't need; I do want to set up good practices and guidelines for logging for the two teammates I have, so we can infect the code with good monitoring and logging

0:32 and writing (log/info "New user submitted some params: " params) is obviously JankTown

0:32 bitemyapp: sritchie: AOP.

0:33 if your functions are granular enough you will have a glorious time with AOP + logging.

0:33 sritchie: time to read up :)

0:33 bitemyapp: sritchie: https://github.com/technomancy/robert-hooke

0:33 sritchie: https://github.com/michaeldrogalis/dire

0:34 sritchie: http://en.wikipedia.org/wiki/The_Art_of_the_Metaobject_Protocol

0:34 sritchie: crazy Common Lisper stuff, but it works REALLY well for certain classes of problems in Clojure.

0:34 sritchie: I've got it

0:34 interesting, nice links

0:36 haha, this is clearly the best way to log

0:36 jesus

0:36 bitemyapp: sritchie: see?!

0:36 sritchie: and to hook in riemann

0:36 bitemyapp: you separate and unify your logging infrastructure into a family of functions "decorating" application behavior

0:36 sritchie: the only thing missing might be the context of the function call...

0:36 bitemyapp: then you also get a nice big fat red switch for shutting stuff on and off.

0:37 sritchie: well, that's just it. it means your functions aren't granular enough.

0:37 sritchie: if you want to log sub-function (like in let expression) behavior, then make it another fn.

0:37 sritchie: well, say I want to measure various latencies in the context of a particular ring requiest

0:37 request*

0:37 bitemyapp: latencies of queries within the Ring request?

0:37 sritchie: yeah, I hit a GET endpoint,

0:38 and want to time the database functions that occur during that GET request

0:38 bitemyapp: queries -> model-fns -> decorate model-fns with time-logging. You can log the time the Ring handler itself took too.

0:38 ninjudd: <3 <3 <3

0:39 sritchie: bitemyapp: but to actually associate them, you'd need to trap the *request* in a dynamic var; or just make sure your function arguments give you everything you need, I suppose

0:39 bitemyapp: sritchie: don't make a dynamic var, I *BEG* of you.

0:40 sritchie: just keep the request an argument to the dependent functions.

0:40 sritchie: I promise

0:40 bitemyapp: sritchie: want to hear a trick? Add a default middleware to your Ring app to inject a UUID into all requests. Boom, unique-ified application tracing via a univeral request argument.

0:40 sritchie: now you can thread application state + arguments + fn calls based on timestamps + UUID

0:41 now you see EVERYTHING

0:41 sritchie: :)

0:41 bitemyapp: I really like this stuff.

0:41 sritchie: yeah, then group by some UUID in Riemann

0:41 bitemyapp: I like how far Ring lets me take simple functions and closures.

0:41 sritchie: yeppers!

0:41 sritchie: and report the percentages

0:41 boom

0:41 awesome

0:41 okay, so here it is:

0:41 Riemann for anything structured; just stats for now in startup mode,

0:42 then down the road, have Riemann forward to elasticsearch

0:42 timbre for text logging, and grep like a champion

0:42 apply logging with robert-hooke, or dire, or whatever

0:42 bitemyapp: sounds good to me.

0:42 sritchie: I'd assume there's no real performance hit (beyond what you'd get by hardcoding the log statements), since you're just rebinding the vars

0:42 bitemyapp: decide on some fairly regular columnal formats with the textual logs and it should be pretty processable with cut or awk.

0:43 sritchie: right.

0:43 it's all just alter-var-root in the end.

0:43 and a function closure.

0:43 sritchie: such is life

0:43 yes

0:43 bitemyapp: which are fast in Clojure.

0:43 sritchie: objects are a poor-man's closures… closures are a poor-man's objects...

0:43 ahhh

0:43 so good

0:43 there's so much amazing stuff to work on

0:43 bitemyapp: the pattern in my Clojure code seems to be that closures are function factories.

0:44 which is the alternative to using stupid global singleton atoms for configuring function behavior. *mutter mutter*

0:44 but really, the higher art form is what Stuart Sierra does.

0:44 he has record-protocol factory thingies

0:44 that lets him create whole-app-system instances.

0:44 like ML functors.

0:44 I...am not that ambitious.

0:44 sritchie: yeah, I've taken that advice

0:44 for our small system

0:45 the whole lifecycle idea is beautiful

0:47 bitemyapp: sritchie: ultimately the evolutionary shift is towards place-independent values.

0:47 sritchie: that's the real sin of global singletons. the singleton place-ness.

0:48 I do leave a few trap doors in my servers though. defonce'd short-circuiting fns for my nrepl and kttp-kit instances for example.

0:48 sritchie: okay, gotta run

0:48 great talk

0:48 thanks for the advice

0:48 feels good to understand the landscape a bit better.

0:49 bitemyapp: sross07: cheers.

0:49 er

0:49 he left :(

1:28 SegFaultAX: bitemyapp: Why not just emit structured log data?

1:30 bitemyapp: SegFaultAX: forall Startups : (laziness > *)

1:30 SegFaultAX: I sometimes wonder why more people don't just emit json or something similar from their loggers.

1:30 bitemyapp: well that was one of the suggestions

1:30 I was just applying the razor of YAGNI to his problem

1:31 SegFaultAX: Sure, but encoding as json isn't that much more work over CLF

1:32 It has the added benefit of completely decoupling log producers from log consumers.

2:06 gdev: SegFaultAX, thats what I was trying to say 3 hours ago

2:08 SegFaultAX: gdev: Hmm?

2:08 Oh, on logging?

2:08 gdev: what you said 30 minutes ago was what I was getting at 2 hours ago

2:09 ddellacosta: whatever happened to futile or whatever his name is?

2:10 SegFaultAX: gdev: Yea.

2:10 gdev: I missed that part of the convo.

2:10 gdev: sometimes I feel like I'm the only one who saw Mark McGranaghan's talk

2:11 SegFaultAX: Which one?

2:11 gdev: SegFaultAX, yeah I was just pointing it out because I'm glad someone had the same idea

2:11 arrdem: gdev: which one? I'm curious now.

2:11 gdev: SegFaultAX, https://www.youtube.com/watch?v=rpmc-wHFUBs

2:13 SegFaultAX: gdev: Ah yes.

2:17 Does he still work at Heroku?

2:18 gdev: according to twitter he does

2:24 and according to github; that's two reliable sources

2:31 seriously_random: why is array named "vector" in this language?

2:36 bitemyapp: seriously_random: because it's not an array.

2:36 seriously_random: arrays are a different thing.

2:36 seriously_random: you're mistaking the appearance for the reality.

2:37 seriously_random: bitemyapp, but why name them vectors?

2:38 bitemyapp: because that's what they are

2:38 arrays are something else.

2:38 I don't know how to make this any more explicit.

2:38 arrays and vectors both exist. vectors are not the same as arrays.

2:38 seriously_random: vectors are not arrays.

2:38 seriously_random: arrays are not vectors

2:38 seriously_random: say it. Say it out loud. Scrawl it on your face with sharpie.

2:39 hyPiRion: I thought vectors were a subset of arrays

2:40 bitemyapp: hyPiRion: In what context? I'm talking about Clojure.

2:40 arrays mean different things to different people in different contexts. In Clojure it's most likely a Java array.

2:40 hyPiRion: bitemyapp: general programming context

2:41 bitemyapp: I don't think `subset` has a well defined meaning here.

2:41 SegFaultAX: hyPiRion: Probably most people consider a vector to be a resizable array.

2:41 gdev: ,(class ["duck" "duck" "goose"])

2:41 bitemyapp: which Clojure vectors aren't really.

2:41 clojurebot: clojure.lang.PersistentVector

2:41 SegFaultAX: Java's analog is an ArrayList

2:41 Or a std vector in C++

2:41 hyPiRion: SegFaultAX: oooor Vector :D

2:42 ,(import 'java.util.Vector)

2:42 clojurebot: java.util.Vector

2:42 bitemyapp: that's not a Clojure vector and you know it.

2:42 hyPiRion: ,(doto (Vector.) (.add 1))

2:42 clojurebot: [1]

2:43 hyPiRion: sure, there's just a naming conflic

2:43 *name conflict

2:43 SegFaultAX: I'm just saying from a general programming/CS perspective, that's probably a reasonable definition.

2:43 hyPiRion: yeah

2:45 bitemyapp: http://stackoverflow.com/questions/508374/what-are-vectors-and-how-are-they-used-in-programming

2:45 SegFaultAX: /Most/ vectors I've seen are backed by arrays as opposed to eg linked lists, but I'm not sure if that's a necessity.

2:45 bitemyapp: looks like most people use the STL definition of what a vector is.

2:45 SegFaultAX: I think the point is the mostly contiguous memory representation

2:45 SegFaultAX: otherwise linked list / stitched linked lists would suffice.

2:45 SegFaultAX: Well then there you go.

2:46 bitemyapp: I have a hard time thinking of Clojure vectors as being identical to the STL definition, let alone arrays themselves.

2:47 SegFaultAX: Well they aren't classical vectors, so there's that.

2:47 bitemyapp: the reference values aren't contiguous in memory.

2:47 that's the real point.

2:47 to remove indirection so the cache can do its thing.

2:47 SegFaultAX: Well, they /may/ not be contiguous.

2:47 bitemyapp: how could you guarantee that? batching the creation of the vector?

2:48 I think realistically the moment you cared about performance you'd use an array or matrix library.

2:48 SegFaultAX: Each node in the vector has 32 contiguous cells

2:48 bitemyapp: I know that, but I don't think that's good enough in the cases where you'd care about cache locality.

2:49 in typical use-cases it's totally fine.

2:50 too bad there aren't any value types in Java :(

2:50 packing longs and structs into arrays would be fun.

2:51 noprompt: hey fellas, how's it going? :)

2:51 SegFaultAX: Java has primitive types.

2:51 noprompt: Howdy.

2:51 bitemyapp: noprompt: glad to see you again!

2:51 SegFaultAX: bitemyapp: int long bool float double etc.

2:51 bitemyapp: noprompt: hacked some Haskell with a buddy yesterday, going to do it again with a different person this Saturday. you're missing out.

2:51 noprompt: bitemyapp: was sick for the past few days. just checked out. :(

2:52 bitemyapp: SegFaultAX: yeah but the point is you can't have a primitive value struct.

2:52 SegFaultAX: That's different from what you said.

2:52 bitemyapp: SegFaultAX: so you have to do SOA instead of AOS, which is possibly annoying/bad depending on access patterns.

2:52 noprompt: bitemyapp: if that's your way of saying you'd like to screenshare/pair on some haskell code, i already told you, i'm down.

2:52 bitemyapp: SegFaultAX: you're right, you made it more precise/detailed.

2:52 noprompt: bitemyapp: :)

2:52 bitemyapp: noprompt: well you'd just seemed busy/harried/etc lately so I didn't want to pester.

2:53 noprompt: bitemyapp: nah. i can make the time. the problem i'm working on atm is not likely going to be solved soon.

2:53 bitemyapp: SegFaultAX: that also means when appending data your arrays, you have to do n-appends to n-arrays depending on how many fields are in your "struct". Really annoying.

2:53 data to your*

2:53 whereas in C/C++ you'd just pack the structs directly into a single array

2:53 clojurebot: No entiendo

2:53 bitemyapp: clojurebot: shush, you weren't beckoned.

2:53 clojurebot: No entiendo

2:53 bitemyapp: ~botsmack

2:53 clojurebot: clojurebot evades successfully!

2:54 bitemyapp: noprompt: this is the sort of stuff I'm doing -- (BE.bShow $ BE.BList [(BE.BInt 10), (BE.BInt 20)]) ""

2:54 BEncode for nrepl protocol (grom)

2:54 I'm still considering rewriting Simonides.

2:54 noprompt: bitemyapp: that looks fun, i remember what $ does.

2:55 bitemyapp: i don't know if that's necissary. but hay, it's your call.

2:55 bitemyapp: noprompt: the parens and invocation of the value bShow returns is because it's using the Data.Text difference list hack.

2:55 noprompt: bitemyapp: that's the type of stuff i don't miss about syntax.

2:55 SegFaultAX: #haskell is a thing :)

2:55 bitemyapp: noprompt: uh, the query generation and input parsing stuff got annoying for me to reason about and my attempt to integrate core.typed was abortive.

2:55 noprompt: bitemyapp: i had the syntax argument today and it's the last time i'm ever going to have it too.

2:55 bitemyapp: so I'd like to just have a real type system on hand so I can be lazy and mash my compile buttonover and over.

2:56 noprompt: bitemyapp: have you looked at prismatic/schema?

2:56 bitemyapp: noprompt: *shrug* I'd prefer S-exprs but it's a small price to pay for TYYYYYYYYYYYYYYYYYYPES

2:56 SegFaultAX: noprompt: Syntax arguments suck. When I talk to my co-workers about Clojure it almost always devolves into "yea but lisp"

2:56 bitemyapp: tired of having to squeeze my brain juice for shit that doesn't matter.

2:56 SegFaultAX: Schema is pretty neat.

2:56 bitemyapp: SegFaultAX: haven't you heard comrade? everywhere is #haskell.

2:57 la revolucion!

2:57 noprompt: SegFaultAX: yep. that's why i'm done. if it's not an algo variant they don't get it.

2:57 SegFaultAX: bitemyapp: Yea but srsly, just go to #haskell if you want to talk about Haskell. Lots of smart folks in there.

2:57 bitemyapp: I knows it, but we have lost souls that need the good word here.

2:57 SegFaultAX: I talked to posco in #haskell the other day, SUPER COOL person.

2:58 noprompt: bitemyapp: did you watch that discussion about talks that dnolen tweeted about?

2:58 bitemyapp: I stopped following him on Twitter awhile back because SJW stuff leaked in.

2:58 noprompt: link?

2:59 SegFaultAX: noprompt: Which is bullshit considering Lisp is essentially the smallest amount of syntax you can have. And Clojure adds just a little more to be nice to programmers.

2:59 SJW?

2:59 bitemyapp: SegFaultAX: dolan pls no

2:59 SegFaultAX: What?

2:59 bitemyapp: my coworker who has just begun learning Clojure said she liked the "tree-like" nature of S-exprs.

2:59 clojurebot: What is meta

2:59 bitemyapp: and how regular it is.

3:00 hyPiRion: SegFaultAX: social justice warrior, iirc

3:00 bitemyapp: this channel needs more dolan duck

3:00 SegFaultAX: also I've asked noprompt to go into #haskell before and failed :P

3:01 and he still isn't in that channel, so...

3:01 SegFaultAX: Probably that means he doesn't want to chat about Haskell.

3:01 bitemyapp: SegFaultAX: he just got done...are you for real man?

3:02 I do not like going through Twitter scrollback of people I intentionally unfollowed to find one reference somebody made.

3:03 noprompt: bitemyapp: took me a minute. http://research.microsoft.com/apps/video/dl.aspx?id=150045

3:03 bitemyapp: it's a pretty long discussion. but eric meyer, if you're familiar with him, makes some interesting points about type systems.

3:03 bitemyapp: I still need to watch that.

3:03 noprompt: you can more or less listen to it.

3:03 bitemyapp: noprompt: Erik Meijer became kind of a crank in the last few years.

3:04 just a fair warning

3:04 SegFaultAX: It's funny, I watched a talk Paul Phillips gave about what's wrong with Scala shortly after he left Typesafe. At the end of the talk, he starts discussing his ideas for how he sees the future of PL research.

3:04 Basically, he describes lisp.

3:04 Like, exactly lisp.

3:05 Well, a typed lisp. But still.

3:05 bitemyapp: Scala was dragged kicking and screaming into macros.

3:05 noprompt: SegFaultAX: yes the argument is generally bullshit magnified by the fact they haven't actually tried lisp or the only lisp they remember is from college.

3:05 bitemyapp: Haskell was dragged not because they didn't know, but because they wanted a safe and principled approach to structural transformation

3:06 then TH happened

3:06 and there was much gnashing of teeth

3:06 SegFaultAX: If you have time, check it out: https://www.youtube.com/watch?v=TS1lpKBMkgg

3:06 It's a really fascinating talk, and Paul is a really excellent speaker (quirky, but excellent).

3:06 bitemyapp: I've seen it.

3:07 noprompt: i need to take a look at this again http://shenlanguage.org/

3:07 bitemyapp: noprompt: no you don't.

3:07 noprompt: bitemyapp: why?

3:07 bitemyapp: noprompt: the type system isn't interesting enough to merit the amount of CRAZY

3:07 noprompt: if you really want to go weird, learn Idris.

3:08 SegFaultAX: noprompt: Shen is pretty fascinating.

3:08 hyPiRion: Agda ploz

3:08 SegFaultAX: At least what little I know about it.

3:08 bitemyapp: hyPiRion: Idris is what the Agda kids moved to.

3:08 noprompt: lol

3:08 bitemyapp: Shen is fascinating like platypus is fascinating.

3:09 It's not particularly lethal or effective, but holy hell is it goofy as shit.

3:09 arrdem: SegFaultAX: I'd agree with bitemyapp here... there's not a whole lot that's interesting about Shen besides the implementation.

3:09 noprompt: ah the staircase of type madness.

3:09 bitemyapp: type le escalier

3:09 noprompt: (you have balls) haskell -> agda -> idris (you have metal balls)

3:09 bitemyapp: you can skip from Haskell to idris.

3:09 jack_rabbit: looks like I need to learn agda and idris.

3:09 noprompt: am i getting this right?

3:10 bitemyapp: Haskell -> Idris

3:10 you'll realize, eventually, in Haskell that you just want dependent types. then you'll use idris. then you'll go to your day job and use JavaScript and contemplate suicide.

3:10 the future is here...but unevenly distributed.

3:10 jack_rabbit: :(

3:11 hyPiRion: where does Coq fit into this crazy type system model?

3:11 ered: i haven't gotten too much into hardcore type stuff yet

3:11 the most i've used so far is like, schema

3:11 SegFaultAX: ered: You haven't even scratched the surface. :D

3:11 bitemyapp: hyPiRion: Coq is a degenerate Agda or Idris.

3:12 hyPiRion: I thought it was beyond Idris in terms of power, like universe constraints and the like

3:12 ered: SegFaultAX: yeah probably not, but hey even schema is helpful

3:12 bitemyapp: Coq has more labor poured into it, but I think it's easier to write proofs and get useful feedback in Agda.

3:12 ered: it at least got me out of the "why the fuck is there a ClassCastException here? what's returning the wrong thing?"

3:12 SegFaultAX: ered: That's not a negative. But type theory is a whole new world.

3:12 bitemyapp: Coq is kind of inane in comparison.

3:13 Coq is the most industrialized for hardening an OCaml codebase, but I'd rather use something in Haskell.

3:14 noprompt: i'm going to go out on a limb here and assert that javascript is probably worse than php in terms of the damage it's caused the world of software.

3:14 bitemyapp: noprompt: I'm not sure. client-side JS at least can't shell out directly.

3:14 I've seen people do some insane stuff in PHP.

3:15 SegFaultAX: noprompt: Yeeeeaa, no. PHP wins 10 times out of 10.

3:15 jack_rabbit: PHP makes me want to kill myself just thinking about it.

3:15 hyPiRion: PHP is okay, because I don't have to use it in my browser.

3:15 SegFaultAX: jack_rabbit: Whoa, calm down bro. It's just a programming language.

3:15 bitemyapp: hyPiRion: coalgebraic codata in Agda are less punishing than Coinductive streams in Coq.

3:15 noprompt: hyPiRion: and that's rub.

3:15 jack_rabbit: SegFaultAX, I'm... I'm so sorry.

3:16 noprompt: the fact that it's everywhere amplifies the horror.

3:16 bitemyapp: noprompt: just pretend it's a form of assembler.

3:16 noprompt: a compiler target. then move on with life.

3:16 CLJS/Fay -> JS and go home happy.

3:16 jack_rabbit: I once took on some freelance job. After I agreed to do it, the guy informed me he wanted it done in PHP. I began working on it to find that none of the software he wanted me to use had PHP apis. After some weeks of parsing XML, I gave up.

3:16 SegFaultAX: Ugh, that "bytecode of the internet" argument really bugs me.

3:16 arrdem: SegFaultAX: THANK you

3:17 noprompt: bitemyapp: i will agree this is the only good thing about having it run everywhere.

3:17 bitemyapp: I don't think it's really true or totally feasible yet, but I'm happy to pretend the DOM API exists to serve non-JS languages.

3:17 I don't think JS is the bytecode of the internet, I just know how to avoid having to write it manually.

3:17 jack_rabbit: I've learned to stop accepting freelance work involving PHP or XML.

3:18 jack_rabbit: I wouldn't have if I knew it was PHP up front.

3:18 bitemyapp: you accept contracts without investigating the tech involved?

3:18 yeesh man.

3:18 jack_rabbit: It was a friend running a small bike shop business.

3:18 No contract.

3:18 SegFaultAX: We all make mistakes when we're young.

3:19 noprompt: jack_rabbit: you should have told him about idris. lol.

3:19 bitemyapp: LOL

3:19 jack_rabbit: XD

3:19 bitemyapp: (Idris is actually kinda new'ish though)

3:19 just uh, fyi.

3:19 Agda is the oldie. Coq is the ugly hag.

3:19 SegFaultAX: "I can only verify that your website is correct, not that it works."

3:19 noprompt: bitemyapp: hey what about the clean language?

3:19 jack_rabbit: I was trying to convince him about C# or Java at least, and I'm not a big fan of those either.

3:19 bitemyapp: noprompt: no reason to use over Haskell.

3:20 SegFaultAX: C# is actually a pretty decent language.

3:20 I just wish the VM wasn't coupled to MS.

3:20 bitemyapp: http://homotopytypetheory.org/2012/01/19/inductive-types-in-hott/

3:21 SegFaultAX: I got to paragraph 3 then gave up.

3:21 noprompt: when oreilly had that cyber monday sale i picked up the ocaml book and some ml books. i feel obligated to learn r or ocaml.

3:21 SegFaultAX: I don't have the brainpower or background to parse that content.

3:22 bitemyapp: SegFaultAX: get the HOTT book!

3:22 SegFaultAX: bitemyapp: No application for it.

3:22 bitemyapp: application is for poor people.

3:22 noprompt: HA!

3:22 bitemyapp: Don't be a pleb, learn for fun.

3:23 noprompt: bitemyapp: that's usually the intent! haha!

3:23 SegFaultAX: I literally can't parse this sentence: "The main theorem is that in HoTT, what we call the rules for homotopy W-types are equivalent to the existence of homotopy-initial algebras for polynomial functors."

3:23 * noprompt is still laughing.

3:23 bitemyapp: SegFaultAX: http://ncatlab.org/nlab/show/homotopy+type+theory

3:24 * arrdem backtracks searching for a comma, fails and throws an error

3:24 bitemyapp: SegFaultAX: http://ncatlab.org/nlab/show/W-type

3:24 arrdem: ?

3:24 SegFaultAX: I'll stick to stuff I care about.

3:24 noprompt: oh the irony of that sentence.

3:24 bitemyapp: In the modern perspective (or at least, from the nPOV) homotopy theory is the higher category theory of (∞,1)-categories: those ∞-categories in which all k-morphisms for k>1 are invertible.

3:25 noprompt: bitemyapp: bro.

3:25 bitemyapp: just clarifying homotopy theory and W-types separately.

3:25 noprompt: hack hack hack

3:25 * noprompt literally has tears in his eyes.

3:25 bitemyapp: somebody get an oxygen mask for this dude.

3:25 SegFaultAX: bitemyapp: Mmm, yes. Indubitably my good man.

3:25 arrdem: noprompt: hang in there buddy

3:25 * noprompt is cough laughing.

3:26 bitemyapp: okay okay, it's like Inception. We need to go deeper!

3:26 Higher category theory is the generalization of category theory to a context where there are not only morphisms between objects, but generally k-morphisms between (k−1)-morphisms, for all k∈N.

3:26 arrdem: bitemyapp: gooby plz no wai

3:26 bitemyapp: for which - Category theory is a toolset for describing the general abstract structures in mathematics.

3:27 SegFaultAX: Actually the last 2 quotes make perfect sense.

3:27 noprompt: posts a link to blog post 0.01% programmers can understand, says "learn for fun", doesn't realize this isn't some people's idea of "fun".

3:27 bitemyapp: For which, k-morphisms are: In an n-category, or most generally an ∞-category, there are many levels of morphism, parametrised by natural numbers.

3:27 SegFaultAX: noprompt: I'd be surprised if the number is that big.

3:27 noprompt: bitemyapp: i <3 your enthusiasm man. :) it's awesome.

3:28 SegFaultAX: bitemyapp: No more copy pasta please.

3:28 bitemyapp: noprompt: listening to Dr. Dre while doing this, if that does anything for you.

3:28 SegFaultAX: fine fine.

3:28 SegFaultAX: <3

3:28 noprompt: bitemyapp: honestly, i'm not trolling you here dude. i really mean. it's great. i have a hole in my heart that stopped being filled when i stopped studying abstract algebra.

3:29 SegFaultAX: Oh oh, it's time for my favorite gangsta rap.

3:29 bitemyapp: noprompt: I think if you liked abstract algebra you're really going to enjoy Haskell.

3:29 * noprompt listening to some terrible 80's pop music from japan.

3:29 noprompt: bitemyapp: i did enjoy haskell.

3:29 bitemyapp: noprompt: you've read this right? http://www.haskell.org/haskellwiki/Typeclassopedia

3:29 SegFaultAX: It's literally one of the most depressing songs I've ever heard.

3:30 noprompt: bitemyapp: i've programmed with it for ~6 months on/off during my free time.

3:30 bitemyapp: noprompt: typeclassopedia is programming+algebra porn.

3:30 hrm. I can craft a tweet from this.

3:31 noprompt: @gvanrossum Turning into your 12 y/o? No wonder you write Python for a living.

3:32 that was sort of a burn on my coworkers and myself too though.

3:33 noprompt: bitemyapp: you said that to him?!

3:33 bitemyapp: noprompt: yeah. twattled.

3:33 I troll him like every week.

3:33 not that he notices or anything, but it amuses me to mock other peoples' gods.

3:34 SegFaultAX: bitemyapp: Ew, I hate the tweet right before that.

3:34 bitemyapp: SegFaultAX: mine or his?

3:34 SegFaultAX: lrn2prefixnotation n00b. amiritegaiz?

3:34 Yours.

3:34 arrdem: clojurebot: bitemyapp |is| it amuses me to mock other peoples' gods

3:34 clojurebot: You don't have to tell me twice.

3:34 noprompt: bitemyapp: dude that's the best thing ever.

3:35 SegFaultAX: arrdem: Some men just want to watch the world burn.

3:35 noprompt: bitemyapp: i'm tired of arguing python guys about how shitty python is.

3:35 bitemyapp: noprompt: I'm tired of writing bad Python code to prove my point.

3:35 noprompt: did I tell you about my "implicit parameters" hack in python?

3:35 it was GREAT

3:35 arrdem: SegFaultAX: I typically count myself among the marshmallow toting spectators hoping for a show... bitemyapp here brings his own flamethower just to make sure there is one.

3:35 bitemyapp: I was pairing when I wrote it, my pair partner nearly lost his mind.

3:35 noprompt: do tell.

3:35 arrdem: bitemyapp: oh please no not the decorators

3:36 bitemyapp: arrdem: oh it's better than that.

3:36 noprompt: needed to eliminate dangerous threadlocal.

3:36 SegFaultAX: arrdem: decorators are awesome!

3:36 arrdem: all hands brace for impact...

3:36 SegFaultAX: I've seen them legitimately used. rarely.

3:36 bitemyapp: noprompt: eliminated dangerous threadlocal by recursing the VM exposed stack objects and looking for an object of a given name and type in the _locals() of each stack object until it found a matching one, returning that.

3:36 SegFaultAX: arrdem: They're just normal HOFs with special syntax, what's the big deal?

3:37 bitemyapp: noprompt: this eliminated the threadlocal at the expense of some slowdown and a 15 line function nobody in my company will ever...ever...ever understand.

3:37 arrdem: ^^ you should enjoy this.

3:37 arrdem: bitemyapp: I read it.

3:37 bitemyapp: plus side? tests pass now.

3:37 SegFaultAX: bitemyapp: gist it, yo. I wanna see.

3:37 noprompt: yes plz.

3:37 bitemyapp: hrm...okay.

3:37 noprompt: plz gist.

3:38 * bitemyapp grabs work computer

3:38 noprompt: SegFaultAX: oh yeah, so one of the guys i work with wants the sort of "real" meta programming lisp affords w/o the lisp.

3:38 arrdem: man if #clojure does this regularly I may have to change my sleep schedule to make it to this...

3:38 noprompt: SegFaultAX: it's like wat. :|

3:39 SegFaultAX: noprompt: Hmm?

3:39 bitemyapp: https://gist.github.com/bitemyapp/7887449


3:39 I was cackling so hard when I wrote that.

3:39 arrdem: bitemyapp: that's actually pretty baller.

3:40 SegFaultAX: That's not that bad.

3:40 bitemyapp: "not that bad" this is how I know Python and Ruby coders aren't to be trusted.

3:40 noprompt: arrdem: oh yeah, at this hour it get's pretty funny.

3:40 SegFaultAX: I mean in terms of complexity.

3:40 bitemyapp: hum. it's easy to understand in isolation.

3:40 but it's horribly dangerous.

3:40 arrdem: noprompt: I was wondering why without fail I've gotten a doge from bitemyapp at about 3am local

3:40 bitemyapp: if anybody other than the web stack makes a request.user, we're going to pass the wrong data.

3:41 noprompt: he gets pinged by his phone, so I make certain a shibe keeps him warm in bed.

3:41 noprompt: bitemyapp: so lol.

3:41 SegFaultAX: Let's be honest, the bigger problem here is the mixing of " and '

3:41 bitemyapp: SegFaultAX: nuh-uh, has a specific meaning in Python.

3:41 SegFaultAX: "" is values, '' is keys.

3:41 nice try!

3:41 arrdem: SegFaultAX: http://img.pandawhale.com/54546-Cheers-Toast-gif-OLQT.gif

3:42 SegFaultAX: arrdem: There is no special meaning.

3:42 And either way, request is a key in this context

3:42 bitemyapp: oh my god how is this JIRA thread about deploying a server 20 comments long?

3:42 SegFaultAX: So it should be '' in both places.

3:42 noprompt: SegFaultAX: you know i hate that about ruby, python, javascript and any other language that didn't have the decency to just come up with a fucking use for ' and just left one path (") to strings.

3:42 bitemyapp: SegFaultAX: it doesn't look key'ish enough.

3:42 noprompt: you forgot Python docstrings

3:42 noprompt: ", ', and """

3:42 noprompt: and Ruby HEREDOCS

3:42 SegFaultAX: But in ruby ' and " are actually different.

3:42 noprompt: bitemyapp: oh yeah, fuck those too.

3:43 arrdem: the """ thing is actually kinda nice...

3:43 bitemyapp: I actually kinda want docstrings :(

3:43 lets me elide escaping inner strings.

3:43 I hate typing string values in docstrings in Clojure, I need muh """

3:43 SegFaultAX: Triple quotes and heredocs are great.

3:43 noprompt: SegFaultAX: yes and the difference is fucking retarded.

3:43 SegFaultAX: noprompt: Not really.

3:43 lumafi: bitemyapp, and don't forget that you can use both ''' and """, and for any string (not just for docstring)

3:43 bitemyapp: oh cool, my coworker understands the hare-brained way I deploy shit.

3:43 I don't even have to explain anything.

3:43 SegFaultAX: noprompt: Disallowing interpolation is useful.

3:43 bitemyapp: lumafi: yeah they're all just values. I forgot you can use ''' though.

3:44 noprompt: SegFaultAX: fuck that.

3:44 it's a waste.

3:44 SegFaultAX: noprompt: I hope you don't use basically any shell ever, then.

3:44 noprompt: it adds more decisions, more cognitive overhead, and more places to just flat out fuck up.

3:44 arrdem: I mean... in fairness I think that scala and the lisp family are the only languages with a 'real" use for '

3:45 bitemyapp: arrdem: did you do that on purpose?

3:45 arrdem: are you trying to make us go mad?

3:45 'real" <--- really dude?

3:45 noprompt: SegFaultAX: i'd like to preface all of this by saying i'm fucking idiot.

3:45 arrdem: bitemyapp: it was a typo originally and I left it to chip away at your sanity

3:45 bitemyapp: we're bikeshedding, it's dangerous to say things like that.


3:45 SegFaultAX: bitemyapp: For that, I want to buy you this http://cdn-www.i-am-bored.com/media/monk-dvd-OCD.jpg

3:45 * arrdem takes his turn at uncontrolled laughter

3:45 SegFaultAX: noprompt: Why?

3:46 bitemyapp: just a reminder that: https://github.com/ninjudd/ring-async exists and is freakin' awesome.

3:46 progo: SegFaultAX: that must be intentional :F

3:46 SegFaultAX: Good box set or best box set?

3:46 progo: You bet your ass it is. It's a show about an /extreme/ OCD guy.

3:46 noprompt: SegFaultAX: s/'m fucking idiot/ don't know anything/

3:47 progo: SegFaultAX: I know :>

3:47 SegFaultAX: noprompt: Meh, we still love you. :D

3:47 Also, my buddy tweeted this gif of himself and his fiance and I don't know how to process it: http://cl.ly/image/2S093m2d1W2l

3:48 noprompt: SegFaultAX: i've been doing this programming bit for four years now and each year i understand less and less. the only thing experience has brought me in this craft is figuring out how to avoid writing software that fucks you hard.

3:48 arrdem: SegFaultAX: thank you for sharing the wat

3:48 SegFaultAX: arrdem: Haha, my pleasure.

3:48 I can't stop watching it.

3:49 That's going to be the gif on my next PR.

3:49 bitemyapp: "Signs you work at a startup"

3:49 "you speak in gifs to coworkers they themselves made"

3:50 SegFaultAX: you win dude. You work at the hipster-er company.

3:50 arrdem: it'd be entertaining to build a "links of #clojure" website that's the top 75 last pasted links from the channel with archives. could be a really good read...

3:50 bitemyapp: I can't match firepower of that magnitude!

3:50 SegFaultAX: bitemyapp: I mean in fairness, we did do no less than 2 engagements with pivotal.

3:50 bitemyapp: hrm. might be time for my yearly star wars marathon.

3:50 SOON

3:50 arrdem: SegFaultAX: AAAH. FEWER NOT LESS.

3:50 bitemyapp: SegFaultAX: countable things are fewer.

3:51 SegFaultAX: Your mom is fewer.

3:51 bitemyapp: feuer frei

3:51 noprompt: lol wat.

3:51 SegFaultAX: arrdem: 15 ITEMS OR LESS!!!! Where's your god now?

3:52 arrdem: SegFaultAX: http://i3.kym-cdn.com/photos/images/newsfeed/000/520/073/eb9.jpg

3:52 jack_rabbit: Yes, lets all take our lanugage use from WalMart.

3:52 arrdem: (inc jack_rabbit)

3:52 lazybot: ⇒ 3

3:52 SegFaultAX: arrdem: Haha, oh shit. I actually laughed out on that one.

3:52 (inc arrdem(

3:52 (inc arrdem)

3:52 lazybot: ⇒ 9

3:52 noprompt: arrdem: HAHA!

3:52 gawd. grammar.

3:52 eh.

3:52 bitemyapp: arrdem: HAHAHAHAHAHA

3:52 (inc arrdem)

3:52 lazybot: ⇒ 10

3:53 noprompt: (inc arrdem)

3:53 lazybot: ⇒ 11

3:53 bitemyapp: (inc jack_rabbit)

3:53 lazybot: ⇒ 4

3:53 SegFaultAX: arrdem: Reminds me of this http://www.reactiongifs.us/wp-content/uploads/2013/06/play_times_over_kangaroo.gif

3:53 arrdem: http://i.minus.com/iVtsYj3BSskw7.gif

3:53 * ucb waves

3:54 * SegFaultAX waves at ucb

3:54 noprompt: heheh

3:54 bitemyapp: ucb: hi!

3:54 * arrdem gives a Vulcan salute

3:54 arrdem: SegFaultAX: haha yes love that one

3:54 ucb: hey bitemyapp, SegFaultAX, arrdem

3:54 bitemyapp: ucb: you caught me on one of my insomnia stretches. how goes it?

3:54 * noprompt does a backflip into the punch bowl.

3:54 ucb: bitemyapp: pretty good actually

3:54 bitemyapp: last night we cracked a thing that made performance of riemann (and graphite) crap

3:55 jack_rabbit: sweet.

3:55 bitemyapp: ucb: sweet, what was it?

3:55 ucb: bitemyapp: turns out that, amongst other things, forking off external processes, /very/ frequently and at high speed is not a great thing to do :/

3:55 arrdem: noprompt: now now.. dunno who's mixed what in there. don't drink and (apply), you should know this

3:55 bitemyapp: ucb: :|

3:55 ucb: bitemyapp: who would've guessed.

3:55 bitemyapp: ucb: hey, you should let Python users know that. They don't seem to be aware.

3:55 ucb: heh

3:55 bitemyapp: ba dum tish.

3:56 noprompt: bitemyapp: nice.

3:56 SegFaultAX: bitemyapp: But but, multiprocessing man. Multiprocessing!

3:56 noprompt: bitemyapp: that's their answer to multithreading.

3:56 arrdem: 'night guys. I have a haskell to skin in the morning.

3:56 ucb: night arrdem!

3:57 bitemyapp: noprompt: everytime somebody tells me I could use multiprocessing to solve a problem, I have to clench the chair I'm sitting in with my fists so that I don't pounce on them and projectile vomit into their mouths like a sparrow with hatchlings.

3:57 arrdem: wat

3:57 bitemyapp: arrdem: g'night!

3:57 noprompt: too many lols for one hour.

3:57 bitemyapp: I'm srs :|

3:57 people suggesting multiprocessing == "did you just tell me to go fuck myself?", "I believe I did Bob."

3:58 noprompt: fn.bind(this) :(

3:58 arrdem: (call/cc ... )

3:59 SegFaultAX: arrdem: Nighty night.

3:59 noprompt: poorly named functions and vars are such a source of confusion.

3:59 bitemyapp: I was explaining namespaces, vars, and interning today.

3:59 SegFaultAX: Said no one ever. Pff.

4:00 bitemyapp: I think they understood it at the end.

4:00 noprompt: a good way to name a function is to write documentation about what it does.

4:00 SegFaultAX: I name all my functions with 1 to 2 letters. Shorter is always better.

4:00 bitemyapp: SegFaultAX: so you write like the guy that made J.

4:01 SegFaultAX: noprompt: Documentation tends to interfere with "shorter is always better"

4:01 noprompt: haha. yes.

4:01 SegFaultAX: bitemyapp: Yes, I often invent new symbols for my functions to really ramp up the concision.

4:01 bitemyapp: SegFaultAX: unicode function names or GTFO.

4:02 smiler: APL->clojure

4:02 Or perhaps vice versa

4:02 bitemyapp: smiler: APL is a comonad.

4:02 SegFaultAX: I like to utilize all the unicode space characters (other than 32) to really keep people on their toes.

4:02 igstan: does anyone know of an enhanced clojure syntax definition file for sublime text? the built-in one seems to be missing some stuff, e.g. defprotocol

4:03 bitemyapp: SegFaultAX: brilliant.

4:03 noprompt: igstan: why not just patch the one you have?

4:03 bitemyapp: SegFaultAX: make it subtle, use a unicode dash so that my-var doesn't mean what they think it means.

4:03 I should make a utility to replace unicode symbols with their ASCII equivalents (not punycode, just direct equivs) and vice versa.

4:03 igstan: noprompt: laziness

4:04 bitemyapp: igstan: noprompt has actually made tooling for making syntax definitions

4:04 noprompt: igstan: i have?

4:04 bitemyapp: noprompt: indirectly, wasn't Frak used for vim-clojure?

4:04 SegFaultAX: I also like to use glyphs that have only very subtle connections to the concept they name. Like snowman for destructive deletes. Because you know, snowmen melt.

4:05 bitemyapp: SegFaultAX: so clever much hipster very unicode

4:05 SegFaultAX: wow

4:05 noprompt: bitemyapp: oh right, but that's primarily for the regular expression character classes.

4:05 bitemyapp: noprompt: but you get my meaning. That still helps a lot.

4:05 noprompt: bitemyapp: however, you are correct that it could be used for this very problem.

4:05 bitemyapp: could reuse the regexes at a minimum.

4:05 SegFaultAX: igstan: Can you just make any pattern matching def* use the same rules as def/defn?

4:06 noprompt: bitemyapp: the funnies part about frak is that beyond the case i designed it for i've never really had much use for it.

4:06 bitemyapp: igstan: make certain you use the Clojure symbol regex.

4:06 igstan: SegFaultAX: I guess I can… I'm just not in the mood for yak shaving.

4:06 bitemyapp: noprompt: ah the best tools are like that.

4:06 igstan: what you are complaining about is the apotheosis of yak shaving :P

4:06 noprompt: bitemyapp: apparently some people have found it super useful.

4:06 SegFaultAX: igstan: So you /want/ their hair to get all overgrown and tangled? You monster.

4:06 bitemyapp: not that I'm hating on you, just saying.

4:06 noprompt: igstan: just shave that yak.

4:06 bitemyapp: noprompt: well, there aren't that many nice tools for generating regex.

4:06 SegFaultAX: Shave it real slow like.

4:07 igstan: haha

4:07 bitemyapp: noprompt: there's FSA, Frak, and...?

4:07 noprompt: bitemyapp: FSA?

4:07 igstan: I was supposed to learn some core.logic, not fiddle with regexes :(

4:07 bitemyapp: noprompt: finite state automata generators

4:08 noprompt: igstan: that's yak shaving yo. just deal w/ it.

4:08 SegFaultAX: igstan: Why not both!?

4:08 noprompt: lol

4:09 igstan: you can use frak to help you with your problem. (frak/string-pattern ["defrecord" "defprotocol" ...])

4:09 ucb: I had completely forgotten about frak

4:10 igstan: noprompt: I've used some duct tape, as per SegFaultAX suggestion. This will do it for the time being: def[^\s]+

4:11 noprompt: igstan: honestly that's probably the best route.

4:12 god. i hate applications. i like text. what can i say?

4:12 bitemyapp: I mentioned off-handedly at a lunch with my coworkers that I wasn't the CS type

4:12 they were aghast.

4:13 noprompt: oh no! not another one!

4:13 ucb: heh

4:13 bitemyapp: noprompt: well, they disagreed with me.

4:13 noprompt: and said that I was one of the most rigorous programmers there. Then I remembered I work at a Python shop.

4:13 jk jk jk I love my coworkers. <3

4:14 ddellacosta: oh snap

4:14 SegFaultAX: bitemyapp: Sick burn

4:14 noprompt: "sick burn" lol

4:15 bitemyapp: ddellacosta: to properly represent my coworkers, they're a diverse group. There are bio people that are usually split across two domains, then there is a contingent of disaffected Scala users.

4:15 ddellacosta: then there's me simultaneously spreading Clojure, Datomic, and Haskell at my company all at once.

4:15 ddellacosta: how are you by the way? long time no see.

4:15 ddellacosta: bitemyapp: sounds like an interesting group. :-)

4:15 bitemyapp: well the Scala users spend most of their time moping about how they can't use Scala.

4:15 ddellacosta: bitemyapp: I'm okay. Kinda burnt out at the time being, been pushing hard lately

4:15 bitemyapp: I spread the languages I like >:)

4:16 ddellacosta: aww. burnout is no good. Can you take a mental health day/week?

4:16 long weekend?

4:16 jack_rabbit: like a virus...

4:16 ddellacosta: bitemyapp: btw, I have an blog post I'd love for you to read if you wouldn't mind taking a gander

4:16 bitemyapp: ddellacosta: I'd be honored!

4:16 jack_rabbit: not far from the truth.

4:16 ddellacosta: bitemyapp: yeah, I will soon, we are just trying hard to get into the next phase

4:17 bitemyapp: http://davedellacosta.com/cljs-dom-survey

4:17 bitemyapp: the scary part is by the time the "clojure + datomic" wave reaches the outer circles of my company, I will have already converted some people to learning type theory and Idris.

4:17 noprompt: at least you're not spreading more python. god. that'd be, like, spreading gonorrhea.

4:17 ddellacosta: thanks!

4:17 bitemyapp: article I mentioned I would write on IRC, oh a month ago. "I'll do it this week!" haha...*sigh*

4:18 noprompt: ddellacosta: ah, souce-code pro, no, no, no, bro!

4:18 ddellacosta: noprompt: ?

4:18 bitemyapp: ddellacosta: no no, do not punish self for creating things. Reward yourself for having put something out there!

4:18 ddellacosta: get milk tea! a snack!

4:18 noprompt: ddellacosta: oh down vote, down vote. :P

4:18 ddellacosta: noprompt: I don't understand, what?

4:18 noprompt: ddellacosta: pick a readable monospaced font.

4:19 bitemyapp: I'm not fond of that font either, looking at it on a Mac in Safari right now.

4:19 ddellacosta: bitemyapp, noprompt: so, you don't like the font I used for code examples? Okay, noted. I was on the fence about that too.

4:19 maybe should just use whatever the default is

4:19 noprompt: ddellacosta: go for something like oxygen or liberation mono if you're gonna use an open source monospaced font.

4:19 ddellacosta: those are pretty readable.

4:19 bitemyapp: ddellacosta: in Linux, Monospace is good. For Mac clients, Menlo. For windows, there's one that starts with a C.

4:19 ddellacosta: noprompt, bitemyapp: cool, thanks for the tips

4:20 TEttinger: calibri?

4:20 ddellacosta: will swap it out

4:20 TEttinger: consolas?

4:20 bitemyapp: TEttinger: think so?

4:20 either/or?

4:20 noprompt: TEttinger: HA!

4:20 bitemyapp: I'm not very opinionated.

4:20 ddellacosta: is it impossible to read without that? I'm really concerned with the content

4:20 bitemyapp: also, everybody get the paddles out, time to spank the windows user.

4:20 ddellacosta: I'm focused on the content, again, was just pitching in.

4:20 noprompt: ddellacosta: i'm obsessed with monospaced fonts. i have a FAT collection.

4:21 TEttinger: noprompt, I will one-up that. I've made a small collection of them.

4:21 ddellacosta: bitemyapp: oh, definitely, sincerely asking though. If it is too painful to read the code examples then I'll swap it out now

4:21 I'm so close to it I think it's easy for me to miss that kind of stuff

4:21 bitemyapp: ddellacosta: I can manage, but the collection literals such as ( and [ are a little hard to see.

4:21 it's indented nicely anyway.

4:21 ddellacosta: bitemyapp: okay. Definitely will swap that out ASAP.

4:22 bitemyapp: ddellacosta: noprompt has done some work with two-way binding and core.async in the browser recently.

4:22 TEttinger: noprompt, I don't think I tagged them all right, but http://fontstruct.com/fontstructors/elementalist/fontstructions/tags/Mono

4:22 bitemyapp: ddellacosta: he was working on it to get away from AngularJS, incidentally.

4:22 ddellacosta: you should check his github.

4:22 noprompt: have you been pushing?

4:22 ddellacosta: bitemyapp: yeah, actually I've been doing a ton of messaging + core.async + reactive kind of stuff on the client w/CLJS lately

4:22 bitemyapp: ddellacosta: there's an easy to use fallback to addEventListener that adds IE8 support if you want it.

4:23 I think I use it in Simonides.

4:23 noprompt: bitemyapp: i stopped working on beltway once i got my new job. really i think i got what i wanted out of it which was the repository concept.

4:23 bitemyapp: noprompt: repository ~= model?

4:24 noprompt: ins + outs?

4:24 ddellacosta: bitemyapp: right, there are plenty of one-off shims for many things. But the point is to evaluate general approaches rather than suggesting folks do a bunch of stuff like that--I assume anyone doing that knows exactly what they want anyways.

4:24 bitemyapp: sure.

4:24 noprompt: bitemyapp: i don't know what else to call it but basically it's just mutable peice of state that publishes messages whenever it's state changes.

4:24 ddellacosta: noprompt: that sounds exactly like what I'm doing. I think we're going to see this approach popping up all over w/core.async.

4:24 noprompt: ddellacosta, bitemyapp i do have the work i did on beltway still and would defintely be open to sharing what i have.

4:24 ddellacosta: it is just so much cleaner

4:25 noprompt: yeah, I want to write something up so I'd love to see it

4:25 bitemyapp: noprompt: well. It's not like I'd mind getting away from AngularJS.

4:25 ddellacosta: bitemyapp, noprompt: I want to get something together as far as all the approaches people are taking who are actually using core.async w/CLJS in production

4:25 bitemyapp: ddellacosta: I was looking at ninjudd's work with Ring async (core.async) recently

4:26 pretty nifty.

4:26 ddellacosta: bitemyapp: cool, I'll have to check it out.

4:27 bitemyapp: ddellacosta: that was a fantastic article with thorough and well-done comparisons. Might I suggest that you be a bit more opinionated though?

4:27 noprompt: ddellacosta: yes. basically a repository is just pub/sub around a peice of state. the state should be a map. the idea is you push/pull messages from the repository.

4:27 bitemyapp: ddellacosta: most people that read your article might be looking for a, "yeah, but what am I supposed to use?" - consider serving that need.

4:27 ddellacosta: bitemyapp: thanks! opinionated: howso?

4:27 bitemyapp: ddellacosta: you're too nice to inferior options :)

4:28 ddellacosta: noprompt: totally.

4:28 bitemyapp: which isn't surprising, given what I know about you.

4:28 ddellacosta: bitemyapp: hmm, I'm hoping folks will pick up on that themselves, but I guess I see your point. Honestly I think it does depend on the needs of the project, to some extent.

4:29 noprompt: ddellacosta: it's very forward and simple to implement. i've basically been hooking this into reactjs.

4:29 ddellacosta: bitemyapp: also, I am super close to Google Closure/Domina, as I use those all the time, and I tried to be reserved in my judgement of those two. I could actually probably write an article *just* on Google Closure and it would be...long.

4:29 noprompt: interesting--I heard David Nolen was playing w/React.js lately too, I'm curious what he's doing

4:29 noprompt: ddellacosta: you should have a look at it. it's super nice.

4:29 ddellacosta: noprompt: but all in all, that sounds really similar to what we've been doing.

4:30 noprompt: definitely will!

4:30 noprompt: ddellacosta: two relavant gists https://gist.github.com/swannodette/7763911 https://gist.github.com/swannodette/7813518

4:31 ddellacosta: noprompt: cool, thanks.

4:31 noprompt: I like your hiccup flavor...nice.

4:31 noprompt: ddellacosta: one note about the blog post. you could use goog.events/listen instead of addEventListener

4:31 piranha: React's good :P

4:31 noprompt: oh haha nm!

4:31 ddellacosta: noprompt: I do in the Google Closure example

4:32 noprompt: ddellacosta: yeah, just scrolled down. (feel like an ass) :P

4:32 ddellacosta: noprompt: no worries...haha. ;-)

4:32 noprompt: piranha: hey, did you see that gist david did with the whole Pure thing?

4:32 piranha: noprompt: what's Pure?

4:32 TEttinger: Pure the Nial-like language?

4:33 noprompt: piranha: i borrowed some of the template code from pump and came up with the defhtmlcomponent macro that makes the whole bit very clean.

4:33 piranha: ah, second one; not yet, looking now

4:33 heh cool :)

4:33 noprompt: piranha: https://gist.github.com/swannodette/7813518

4:33 bitemyapp: ddellacosta: the code is really clean. You're an artisan.

4:33 I feel bad for poking you over the fonts.

4:33 noprompt: piranha: you mentioned you were busy, but i'd be happy to pitch in help if you're open to some of this stuff.

4:33 ddellacosta: bitemyapp: ha...I don't think so but thanks. :-) No, you and noprompt are right to call that stuff out--it's very important that it is readable!

4:34 bitemyapp: Raynes: learning what?

4:35 piranha: noprompt: yeah, I am, I'm actually was playing a bit with pump lately, but still didn't get enough time to push anything out. I hope to get a bit more time later though, that's something I want to see improved (I would like to introduce all of this to my work, I'm tired of JS already)

4:35 also, of course I'm open to changes in pump :)

4:35 noprompt: ddellacosta: also ditch the letter-spacing.

4:35 ddellacosta: noprompt: where?

4:36 piranha: it was written in a hurry...

4:36 noprompt: ddellacosta: i'm seeing a 0.1em letter-spacing when inspect the <pre> elements.

4:36 ddellacosta: noprompt: ah, yeah, I'll probably redo it all if I swap out the code font

4:36 noprompt: piranha: well how can i help?

4:37 ddellacosta: bitemyapp, noprompt: thanks for the feedback! Very helpful.

4:38 noprompt: ddellacosta: is your blog written w/ clojure?

4:38 piranha: noprompt: well major things with pump were a bit painful inclusion of React in projects (I tried to convert React to goog module system, and this almost worked - need to preserve tag names in one place), then drop templating system in favor of functions (since it takes a bit of time to parse) and make interface a bit more clojure-like

4:38 ddellacosta: noprompt: it's just a hacked together thing but yes.

4:38 bitemyapp: ddellacosta: glad I could help, your stuff was too good for me to improve upon though :(

4:38 noprompt: mine is too! 'tis hacky though.

4:38 piranha: I was thinking that maybe having component as a simple function which does render is good enough, and if you want state or componentDidMount handling you'd define it through meta...

4:38 ddellacosta: bitemyapp: that is not true, but appreciated. :-)

4:39 piranha: or no, that feels a bit hackish :( I have some ideas from others, but not sure about them

4:40 also there is a bit of a problem defining event handlers

4:41 noprompt: piranha: drop the template system? i don't know if that's totally necissary. the hiccup notation is very convenient. i mean it's possible to simply write aliases to all of the fns in React.DOM.*. having gained a bit of understand of react i don't know if the hiccup templates are going to be a huge bottle neck.

4:41 bitemyapp: (doubt it)

4:41 piranha: noprompt: well it took around 20% of runtime in our case

4:41 noprompt: piranha: oh rly?

4:41 wow.

4:41 piranha: so I just thought that's a nice way to get your app run faster a bit

4:41 bitemyapp: piranha: is that problematically high?

4:41 piranha: not sure ;)))

4:42 just something we spotted

4:42 bitemyapp: 20% doesn't seem out of the question for naive template code.

4:42 piranha: also, if you look here: https://github.com/wunderwaffle/warmagnet/blob/master/cljs/warmagnet/views/gamemap.cljs#L177

4:42 bitemyapp: I bet it's worse than 20% for most backend web apps.

4:42 Have you seen Rails apps?

4:42 scary.

4:42 piranha: haha yeah, same thing for django

4:42 ok, that's not *very* important :))

4:42 having better API is more important, sure

4:42 but then look at our handlers

4:42 bitemyapp: I'd tend to agree.

4:42 noprompt: piranha: i'll have to benchmark the watered down version i wrote. basically i skipped the tag checks and dropped shorthand notation like :foo.bar#baz.

4:43 piranha: we have them defined in (let ...) inside of render, so that they will know state & props, and then pass them to inner components

4:43 and that's a bit problematic, since those functions are always new on every render, so every inner component has to be re-rendered

4:44 I'm not absolutely sure that is a problem, but... at some points it felt like one

4:44 argh, I had to log all the numbers we had :(

4:44 noprompt: hehe, dropping :foo.bar#baz sounds like a good idea, it spends quite a bit of time there

4:45 noprompt: piranha: syntactic sugar causes cancer of the semicolon ;)

4:46 piranha: even with vanilla hiccup i avoid the css notation because it's not composable and, imho, doesn't read well.

4:46 bitemyapp: I decided I want to learn how lexical scope in Clojure works today.

4:46 piranha: noprompt: on the other hand, how's hiccup's syntax is better than simple function call? :)

4:46 bitemyapp: insomnia should be leveraged to some kind of positive outcome.

4:47 piranha: it's data, not opaque fn values.

4:47 noprompt: piranha: dnolen claims that his "pure" solution should, quote, "blaze"

4:47 piranha: "blaze"?

4:47 * bitemyapp rolls eyes

4:47 piranha: ah, be very fast

4:47 noprompt: piranha: performance wise.

4:47 yes

4:47 bitemyapp: piranha: 420blazeit

4:47 piranha: sure :-) sorry, not native speaker :)

4:48 noprompt: piranha: the thing i like about hiccup vs plain function calls is that it's obvious (to me anyways) where the html is.

4:48 piranha: heh, sure

4:48 noprompt: piranha: no worries. :)

4:49 piranha: each of the templating solutions has it's benefits and drawbacks. i feel that a function based hiccup templating approach is a nice middle ground between plain old functions and a macro based approach.

4:50 piranha: sure

4:50 as for 'pure' - I would love to see something like our GameMap, to be honest :)

4:51 I mean for basic examples there are a lot of very good-looking approaches, but then when you need to do a lot of stuff and you want your component to exist few times and it has it's own state... that's where it gets hairy :)

4:51 noprompt: piranha: looking at it now.

4:53 piranha: defr might be nice as (defclass GameMap (get-initial-state [] ...) (component-will-mount [] ...))

4:53 piranha: noprompt: sure! like defrecord, right?

4:53 I was thinking about that :)

4:53 noprompt: piranha: right.

4:55 piranha: noprompt: that sounds like a good approach I guess...

4:55 our components already implement all atom protocols... :)

4:55 noprompt: piranha: was that so you could access `state`?

4:56 ddellacosta: have you tried using garden for your css?

4:56 piranha: noprompt: yeah, @component == state, and also pr-str works nicer this way

4:56 noprompt: ddellacosta: it's pretty crazy.

4:56 ddellacosta: noprompt: no, I've heard of it, but checked it out

4:57 but *not checked it out

4:57 noprompt: what do you like about it?

4:58 noprompt: ddellacosta: a lot of things. it's funny, you know, i wrote it and didn't get to use it beyond small examples for several months. but because it's just clojure you can implement all sorts of interesting things.

4:58 ddellacosta: noprompt: oh, sorry, I didn't realize it was yours! haha. Will check it out.

4:59 noprompt: ddellacosta: when i left my other job i'd been working something that was fairly css heavy and garden was tripping me out.

4:59 ddellacosta: noprompt: we have a compass solution that works okay. Sometimes I find it frustrating but generally it saves us some time. CSS, in general, I find frustrating though.

4:59 noprompt: ddellacosta: i'd only used sass/compass prior to that.

4:59 ddellacosta: noprompt: I'll definitely have to take a look if it is any advancement on compass, and can be integrated better into a Clojure stack.

5:00 noprompt: that's one problem with all the asset handling stuff out there now, in general. ;-/

5:01 noprompt: ddellacosta: well there's a shitty lein-garden plugin that works well if you have one file but i haven't fixed it for directory changes which makes it worthless.

5:01 ddellacosta: noprompt: well, maybe can be extended, huh?

5:01 noprompt: ddellacosta: also the lack of compass means that some things need to be handrolled.

5:02 ddellacosta: noprompt: I honestly don't know what the best thing to do is. I've seen some folks go so far as to try getting jruby going...which is kind of insane in my opinion, but I understand *why*, as Compass is really useful.

5:02 noprompt: ddellacosta: oh, the other thing, garden can be used on the client too.

5:03 ddellacosta: but it needs some goodies to make that experience compelling. like direct manipulation of the CSSOM.

5:03 ddellacosta: oh, like, embedded in CLJS? That is pretty interesting...

5:04 noprompt: I do feel like we need a better CSS solution in Clojure web land. I will have to invest some time in trying out Garden when I have more time...

5:04 noprompt: I wish we had an exclusively web-focused Clojure survey

5:04 I want to know what everyone doing Clojure/CLJS is doing, how they are using the tools, etc.

5:05 noprompt: ddellacosta: well garden is a pretty solid base but it'd be a better story if more folks could pitch in.

5:05 bitemyapp: hrm. housing is 53% cheaper in seattle than the SF bay area. hrm.

5:05 Austin? 71%. good god.

5:05 noprompt: bitemyapp: it's probably 90% cheaper here.

5:05 bitemyapp: noprompt: 65%. Cheaper than Seattle, more expensive than Austin.

5:06 noprompt: do not underestimate how cheap Austin is.

5:06 noprompt: bitemyapp: would've never guessed.

5:06 ddellacosta: bitemyapp: my 2LDK place in Tokyo is about $1300 a month...right in Meguro too

5:06 bitemyapp: it's like $120k for a house + a few acres of land in Austin.

5:06 ddellacosta: I love me some Austin though

5:06 bitemyapp: ddellacosta: that's kind of upsetting. I'm paying $1200 a month for a room in a house with 11 housemates in an outer neighborhood of SF.

5:06 noprompt: ddellacosta: how'd you get stationed there?

5:07 ddellacosta: bitemyapp: I can understand. Then again, there are no jobs worth speaking of in Tokyo

5:07 bitemyapp: ddellacosta: remote is an ongoing discussion at my company. *prays hard*

5:07 I want to leave SF so bad ;_;

5:07 ddellacosta: noprompt: I stationed myself here, worked for a disappointing Japanese company for a year and a half, then started working remotely for a great small Canadian startup doing Clojure.

5:08 bitemyapp: I wouldn't mind living in SF if I didn't have to contend with the housing situation. But it makes it *so* unappealing, even though it's probably the best place in the world for me, work-wise

5:08 noprompt: ddellacosta: that's pretty rad.

5:08 piranha: heh you guys make my consideration about going to USA/SF less interesting... :)

5:09 noprompt: piranha: where are you at?

5:09 ddellacosta: noprompt: I have no huge complaints. :-) Would like to make more money, but, I live in Tokyo and work remotely with Clojure, so, tradeoffs.

5:09 piranha: noprompt: Ukraine ;)

5:09 ddellacosta: piranha: wow! Would like to visit Ukraine some day.

5:09 bitemyapp: ddellacosta: well, I'm sort of hoping I can shift to remote and work at my current company until I "make my own job"

5:09 noprompt: piranha: ugh. i *so* want to visit eastern europe.

5:09 ddellacosta: bitemyapp: do it man!

5:09 bitemyapp: I'm very at my current company.

5:09 piranha: but I've been thinking about leaving it for some time now, I'm tired of government and would like nicer weather :)

5:10 ddellacosta: yeah, I can imagine the weather is a bit of a killer...

5:10 bitemyapp: ddellacosta: maybe someday hire some devs too?

5:10 piranha: ddellacosta: noprompt: well if you're going to visit Ukraine while I'm here, you're welcome! I could show you around I guess (I'm in Kyiv)

5:10 noprompt: ddellacosta: yes <3 hire us. :P

5:10 piranha: ddellacosta: well it's not as appalling as in the Netherlands (I've lived there for a year)

5:10 bitemyapp: noprompt: you mean me?

5:11 noprompt: bitemyapp: of course. <3 i liked working w/ you.

5:11 ddellacosta: bitemyapp, noprompt: haha, we don't have enough money yet...but we'll see what happens. :-)

5:11 piranha: thanks!

5:12 bitemyapp: noprompt: aww :D

5:12 ddellacosta: who knows, maybe take you up on that some day. My wife loves to travel, and we haven't been to Eastern Europe. Well, I haven't.

5:12 piranha: :)

5:12 bitemyapp: way too many nice people here.

5:12 piranha: bitemyapp: in #clojure you mean?

5:13 bitemyapp: come here and I'll introduce to some less nice people if you want :D

5:13 bitemyapp: yes and in particular this night.

5:13 piranha: :(

5:13 noprompt: igstan: shaving that yak buddy?

5:13 bitemyapp: piranha: feed me piroshkis instead.

5:13 noprompt: lol

5:13 piranha: :))

5:13 igstan: noprompt: neah, done with it already. learning some core.logic now

5:13 bitemyapp: piranha: I lived in Detroit for several years, fond memories of Ukrainian people there.

5:14 noprompt: bitemyapp: people "live" in detroit?

5:14 eh, guess i have no room to talk being in fresno and all.

5:14 piranha: bitemyapp: heh :) well, there is always quite a bit of good people, but some are less nice, especially when you don't have enough money, or are used to effectively robbing country and so on ;) but that's unappealing topic anyway :P

5:15 bitemyapp: noprompt: big words, Fresno man.

5:18 piranha: yeah, lot of unhappiness around the world.

5:18 noprompt: more ways to rob someone than just take their money that's for sure.

5:19 bitemyapp: noprompt: yeah, like the ways dynamic languages have robbed my fucking time with type errors.

5:19 piranha: :)

5:20 * noprompt gets bitemyapp a tissue.

5:20 bitemyapp: noprompt: caremad.

5:20 noprompt: bitemyapp: so when do you wanna do some haskell?

5:21 bitemyapp: noprompt: I have dinner with the ubermensch weds. Haskell Saturday morning. Tomorrow night might be reserved for recovering from my dumbass insomnia.

5:21 noprompt: bitemyapp: i'd like to learn about what your building with grom. because odds are most of the stuff in there that isn't language specific is news to me.

5:21 bitemyapp: noprompt: Thursday night?

5:22 grom is *nothing* special at all, pretty boring.

5:22 noprompt: bitemyapp: should be good.

5:23 bitemyapp: I'm also not really planning to exercise Haskell's super-powers much. Vanilla Network.Socket IO monad stuff.

5:23 if I wanted to be clever I would use Conduit or something.

5:23 or figure out a way to model the network communication as codata.

5:24 noprompt: bitemyapp: yeah, but the whole bit about doing what grenchman does, i'm uneducated in those realms. ie. i haven't done much communication stuff with sockets, etc.

5:24 bitemyapp: I just want to talk to lein repl :headless without building OCaml.

5:24 noprompt: bitemyapp: it is socket stuff right?

5:24 bitemyapp: noprompt: oh. hum. sockets aren't bad at all.

5:24 noprompt: da! nrepl protocol is bencode over TCP sockets.

5:24 associative data. basically maps.

5:24 noprompt: bitemyapp: yeah, i've never done much of that.

5:24 bitemyapp: noprompt: should expose you to some new stuff then, that's great.

5:25 noprompt: bitemyapp: yeah that'd be good. i might actually get some more wacky ideas.

5:25 bitemyapp: noprompt: should be pretty easy for you though, I think you've worked on much harder stuff than this.

5:25 * ddellacosta jealous of people hanging out to talk about clojure

5:25 bitemyapp: I spent most of Sunday exploring a bencode library with my friend.

5:25 * ddellacosta ... in meatspace

5:25 bitemyapp: ddellacosta: be more jealous - I'm meeting techno soon!

5:25 noprompt: bitemyapp: cool. yeah networking/communications is one of those areas i haven't figured out where to get started.

5:25 * ddellacosta *grumbles*

5:25 bitemyapp: ddellacosta: so excited *_*

5:26 noprompt: I'm not into "networking" but I am into databases and protocols (thus my interest in Revise's pipelined connections)

5:26 noprompt: wait...have I showed you Revise's connection model?

5:26 the RethinkDB protocol is TCP sockets + slightly modified protobufs protocol

5:27 noprompt: bitemyapp: negative. i briefly looked at it. i'm considering using rethink for something but currently evaluating dataomic.

5:27 bitemyapp: I find the "semantics" of protocols interesting.

5:27 noprompt: well I use Datomic at work, so if you have questions about either, ping me!

5:27 noprompt: bitemyapp: how do you like it?

5:27 bitemyapp: Datomic has been successful for the sort of things we do at my company.

5:28 I'd need to know a specific use-case to speak to it.

5:28 I'd be perfectly okay with the notion of Datomic as a nice default alternative to PostgreSQL for vanilla OLTP workloads.

5:29 ultimately the practicality of Datomic for your workload could be decided algorithmically

5:30 piranha: how's that?

5:30 noprompt: overengineered bank ocr kata solution https://gist.github.com/noprompt/b07b85881d76c6ecba97

5:31 bitemyapp: (churn rate * dataset size growth rate * base size) == Datomic database size growth rate

5:31 noprompt: was in text search mode when i was hacking on it.

5:31 bitemyapp: because in PostgreSQL your dataset size grows with the number of rows

5:31 in Datomic it grows with the average length of history of per datom plus the number of datoms.

5:32 but it's nicer for OLTP workloads if you're comfortable using Clojure.

5:32 hella lack of documentation though. if you use Datomic, you'll be in here asking me questions.

5:32 piranha: ah, right, so if you have a high churn rate, it'll grow too fast

5:32 bitemyapp: piranha: yeah, but you'd be surprised at what it would take to produce something that wouldn't work.

5:32 very few companies have an OLTP workload with high enough churn for it to matter.

5:33 * noprompt remembers that he has italian prog rock in his music collection.

5:33 piranha: ok, I'm doing a simple game, but I'm more on front-end side of it, so it doesn't matter that much :)

5:33 bitemyapp: noprompt: that solution is pleasing. Declarative, clean, and clever.

5:33 noprompt: bitemyapp: has anyone come up with something to get datomic on the client?

5:33 piranha: what matters is that if I should push clojure asap or start with replacing our data layer with mori first...

5:34 bitemyapp: noprompt: I really like that kata solution.

5:34 noprompt: uh, me?

5:34 CLRS + the two or three Datomic REST APIs I've written.

5:34 I literally just wrote another one (berossus), getting open sourced this week

5:34 my coworkers are working on a Python Datomic OEM (bottom) that I will be contributing to and open sourcing as well hopefully.

5:34 noprompt: bitemyapp: oh you think so? thanks. i came back to it today and thought the set/intersection bit was over engineered.

5:35 bitemyapp: noprompt: nah, I think it's an excellent way to express the problem.

5:35 noprompt: and reflects the nature of what's being described and computed.

5:35 I like it *very* much.

5:35 5rlz.

5:36 CookedGryphon: hi, could someone explain core.async/sub to me? The docstring is useless, and I can't figure it out from the source.... what is the in channel and where do I get an out channel? And what is p?

5:36 publisher? predicate?

5:36 parameter?

5:36 noprompt: bitemyapp: the reduce + set/intersection combo is so fun whenever it comes up.

5:37 bitemyapp: CookedGryphon: this documentation is so terrible, hahaha

5:38 noprompt: CookedGryphon: i think i might be able to help you.

5:38 CookedGryphon: you understand async/pub right?

5:39 CookedGryphon: noprompt: I think so, yeah - hard to verify until i've subscribed to something ;)

5:40 noprompt: CookedGryphon: basically your pub is going to give you back a channel which will contain the results of whatever it's pubfn is.

5:41 CookedGryphon: so for example (def publisher (async/pub (async/chan) :message)

5:41 CookedGryphon: s/message/topic

5:42 seriously_random: opposite of contains? (because google sucks)

5:42 noprompt: CookedGryphon: then you subscribe to some topic (def poetry-subscription (sub publisher :poetry (async/chan))

5:43 CookedGryphon: suppose you then publish a message {:topic :poetry :value "blah blah blah"}

5:43 CookedGryphon: (>! pusblisher message), then (<! poetry-subscription) will have the value {:topic :poetry :value "blah blah blah"}

5:44 CookedGryphon: noprompt: with subscribing, can I subscribe to multiple topics? with (->> (chan) (sub p :a) (sub p :b))?

5:45 noprompt: CookedGryphon: hmm. haven't tried that. normally i would just do two subscriptions and then use alts!

5:45 CookedGryphon: but give it a shot!

5:45 CookedGryphon: okay, will do, that's really helpful, thanks!

5:45 I'll let you know how it goes

5:45 noprompt: CookedGryphon: are you using this client or server side?

5:46 CookedGryphon: on an android phone ;)

5:46 noprompt: oh sweet.

5:46 seriously_random: ah, (not (contains?))

5:46 noprompt: seriously_random: or (complement contains?) lol

5:52 CookedGryphon: noprompt: can I use a put! onto my publisher?

5:52 or do i need to put onto the chan that I give to the publisher

5:53 noprompt: CookedGryphon: i think you can put! on the publisher.

5:53 CookedGryphon: I'm getting no implementation of WritePort on pub$reify

5:54 noprompt: CookedGryphon: oh right. it might be the chan you passed in then.

5:54 CookedGryphon: hmm, that's annoying, does that mean I need to keep track of two things, the pub to subscribe things to and the input channel to put things into it?

5:54 noprompt: CookedGryphon: yeah, try putting values on the channel you passed in https://github.com/clojure/core.async/blob/76317035d386ce2a1d98c2c349da9b898b480c55/src/main/clojure/clojure/core/async.clj#L850

5:56 CookedGryphon: right. i ran in to that too. what i did was create a Broker type for abstracting that.

5:56 CookedGryphon: okay, I think this is probably the core of the issue I've been having then

5:57 noprompt: CookedGryphon: the (deftype MessageBroker [ch topic-fn]) and then a protocol IBroker with publish/subscribe functions. then just create a function like make-message-broker [topic-fn] etc.

5:58 have the make-message-broker fn create the channel in the closure and use the publish [message] subscribe [topic ch] functions implemented for your Broker type.

5:58 CookedGryphon: does that make sense?

5:58 CookedGryphon: yep, thanks

6:01 noprompt: CookedGryphon: cool. hope it works for you. i've mainly used that pattern on the client side and it works decently.

6:02 CookedGryphon: okay, new function, what does a buf-fn expect

6:02 new question*

6:02 bitemyapp: type signatures would really help here.

6:02 seriously.

6:02 noprompt: bitemyapp: troll but true.

6:03 CookedGryphon: okay, the docstring does actually help here

6:03 I just skimmed and assumed a meaning first time around

6:05 noprompt: i've been putting my entire music library on shuffle for days. it's been interesting.

6:05 so much random crap.

6:06 bitemyapp: noprompt: I've wasted too much time trying to reassemble type signatures for clojure code.

6:08 noprompt: bitemyapp: does core.typed help at all in that regard.

6:09 damn this song is beautiful.

6:09 bitemyapp: noprompt: maybe someday, but there are a lot of problems.

6:09 noprompt: ddellacosta: translation? 生誕

6:10 bitemyapp: noprompt: one is that the semantics aren't very powerful, there's too many possibilities for a given function, unions are horrific, and the syntax is hard on the eyes. I think core.typed could help but it's going to need some humanization. Also, not enough libraries use it. Proper hindley-milner supported by a typed-by-default ecosystem with tools like hackage and hoogle would be...lovely.

6:10 noprompt: oh it means birth.

6:10 ddellacosta: noprompt: birth

6:10 bitemyapp: well, the semantics are expressive, but they're not leveraging things like monads to express uncertainty.

6:10 ddellacosta: yep.

6:11 bitemyapp: so instead of encoding uncertainty in something general or powerful, the type system has one big "or" attached to every annotation

6:11 then you get to slap Any -> Any on a bunch of crap :|

6:12 noprompt: bitemyapp: that's a bummer. but ambrose is actively working on it, no?

6:12 bitemyapp: noprompt: yes, on bringing it to CLJS and the DOM API.

6:12 noprompt: bitemyapp: oh dear.

6:12 bitemyapp: noprompt: I want to love core.typed, but the limitations Ambrose is working with are crippling.

6:13 it's a particular evolutionary branch of type systems that was briefly explored and largely left to stay where it planted.

6:13 noprompt: bitemyapp: he seems like he's got a good attitude about it though.

6:13 bitemyapp: for various reasons.

6:13 well it's partly a high level design and practical exercise for him. I think it's a success in that regard

6:13 but when I've tasted the power, it's hard to "make do"

6:14 noprompt: it just kills me that no one has nailed a lisp with a solid type system yet that doesn't feel janky.

6:14 bitemyapp: noprompt: there are multiple fundamentals to Lisps that make it insanely awkward.

6:15 noprompt: well. It's doable. Let me just say that. But you have to plan ahead for it.

6:15 noprompt: bitemyapp: maybe it's the approach.

6:15 bitemyapp: partly that.

6:16 if you were willing to abandon things like "symbols" and not bother to type-check macros, you could make a typed Lisp with hindley milner.

6:16 sorry, when I say abandon, I mean uni-typed references.

6:16 you also have to plan your core API around types.

6:17 noprompt: take a look at the core.typed annotations for Clojure core to see how awkward some things ar.e

6:17 anything with [Any * -> Any] is horrorsville

6:18 noprompt: :/

6:18 bitemyapp: anything with arbitrary arity is WTFBBQ ordinarily, you'd just use function composition and recursion or a collection in Haskell to express the same thing.

6:19 noprompt: you can't generically "apply" in a typed language, (anonymous collection) - you'd use a tuple typed for the specific combination required to be valid arguments for that function.

6:19 noprompt: not that this is a problem in practice. Scala users do it all the time.

6:19 but it means you have to actually make (say) what you want.

6:20 rather than blindly smashing a vector into apply like you do in Clojure

6:20 noprompt: and you don't need apply in Haskell...because the functions are fucking curried!

6:20 noprompt: bitemyapp: right. all functions take only one argument.

6:20 bitemyapp: when you embrace FP properly, you don't need a lot of things that are dirty or inconsistent.

6:21 noprompt: right, so apply in Haskell is just fold.

6:21 noprompt: and if you *REALLY* wanted, you can actually uncurry functions into taking tuples if you want, although that's not the default for various reasons.

6:23 noprompt: well shit man. i think i'm gonna finish setting up this clj project for taming text and get some sleep.

6:24 bitemyapp: noprompt: dream of rainbows, lambdas, and types!

6:26 xificurC: hey any ideas why is it that I can start a `lein repl' session from bash but I cannot from emacs? If I do cider-jack-in I get stuck on `Connecting to nREPL on localhost:50004' or another port

6:27 * ucb sighs

6:27 xificurC: I also tried creating a session from the shell and simply running `cider' and specifying the port but no luck

6:27 ucb: bitemyapp: remember how happy I was a few hrs. ago? not any more :/

6:28 bitemyapp: just unfollowed someone on Twitter because they use Golang.

6:29 ucb: :( ?

6:33 ucb: bitemyapp: networking is hard

6:35 bitemyapp: ucb: I'm sorry you're distressed/unhappy.

6:35 ucb: is there some way I can help?

6:35 i have many pictures of cats and other assorted fuzzy creatures.

6:35 ucb: bitemyapp: ah, no worries. I'm just ranting to release some steam. Because sensu >:@

6:36 well, sensu amongst other things

6:38 bitemyapp: ucb: hum. monitoring. What's up exactly?

6:39 ucb: bitemyapp: just migrating a bunch of hosts to send traffic directly to the monitoring box (right now the traffic goes via an intermediary box). In theory traffic should remain the same, etc. Yet when I migrate the hosts traffic increased a good bunch, etc. Hilarity ensues.

6:40 bitemyapp: ucb: derferk?

6:40 ucb: no idea what that is but maybe?

6:42 bitemyapp: ucb: it's a distorted "dafuq"

6:42 ucb: heh

6:42 then absoluyes

6:43 further, traffic rx by the intermediary box drops by 1k say, yet incoming traffic to the monitoring box only increases by .2k or so

6:43 and yet ... the thing becomes maniacal

6:43 * ucb cackles

6:45 bitemyapp: ucb: is it possible the migration broke reporting to metrics?

6:46 ucb: not really, it's just traffic redirection

6:46 I mean, I'd be super surprised if it were

6:46 bitemyapp: ucb: is it possible the migration fixed reporting to metrics that was previously broken?

6:47 ucb: well, one thing I considered was packet drop between intermediary box and monitoring box effectively acting as a throttling mechanism

6:47 but I'm not convinced that's the case

6:47 bitemyapp: ucb: did you record connection metrics between the intermediary and monitoring box?

6:47 ucb: measured with iperf, etc.

6:48 well, I measured the traffic between I->M

6:48 and it seemed ok

6:49 bitemyapp: oh, there are bounded channels for Haskell. I feel dumb now.

6:53 sm0ke: does anyone faced problems upgrading to compojure 1.1.6? i am getting java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest

6:58 * bitemyapp squints eyes

6:58 bitemyapp: sm0ke: haven't upgraded, let you know if I bump into it.

7:00 sm0ke: although 'lein deps :tree' shows servlet-api 2.5 as a dep

7:03 something fishy with compojure

7:05 ohcibi: hi I get an unsupported operation exception for (count) on a type long... the error happens in some clojures core java-file but I cant see any stacktrace... how to enable the stacktrace?

7:06 sm0ke: AHA!

7:07 compojure 1.1.6 doesnt have servlet api

7:07 actually ring core 1.2.1 doesnt have that

7:08 yep, headsup guys, https://github.com/ring-clojure/ring/pull/89

7:29 Jarda: has someone used http://clojurequartz.info/articles/jobs.html ?

7:30 I need to do scheduled tasks for my webapp

7:31 could I just initialize jobs in my compojure app-handler?

7:55 sveri: hi, i am trying to run this code (clojurescript) in the browser: http://pastebin.com/68YNqptH It compiles, but when i open it in the browser i get this error: "Uncaught Error: Cannot merge $e into node of different type" Does anyone know what this means?

8:05 chrisdone: is this channel publicly logged?

8:05 mdrogalis: chrisdone: Yup

8:06 http://clojure-log.n01se.net/

8:12 chrisdone: ah, someone requested i add #clojure to http://ircbrowse.net/, but seems you already have something similar

8:15 i might scrape all the years from it

8:23 unless anyone has znc logs of this channel?

8:25 * mdrogalis shrugs.

8:42 osa1: hello everone. I'm currently reading Clojure compiler's source. there are huge number of unused methods in RT.java, is there a point in keeping them?

8:42 tbaldridge: osa1: example?

8:43 clgv: osa1: are you sure that they are unused? some of them are probably used (directly or as :inline) in clojure/core.clj

8:43 mdrogalis: I'd kind of like to axe some of those huge blocks of commented code out in the compiler.

8:43 osa1: clgv: I'm not sure. my IDE says that.

8:44 clgv: so are they called using some kind of reflection functionality?

8:44 tbaldridge: osa1: yeah, your IDE probably doesn't understand Clojure

8:44 clgv: osa1: it's probably just analysing the *.java sources

8:44 osa1: hmm yeah that makes sense

8:44 clgv: osa1: no. but they are called from clojure source ;)

8:45 osa1: yeah got it. thanks.

8:51 r4vi: is there a ring/compojure equivilent to Pedestal's url-for? https://github.com/pedestal/docs/blob/master/documentation/service-routing.md#url-generation-1

8:54 bja: r4vi: not to my knowledge. https://github.com/weavejester/compojure/issues/39

8:54 r4vi: bja: thanks

8:55 bja: you might be able to do something close to url lookup if you bind each route to a particular name

8:55 but selecting between arities with the same name probably won't happen easily (if at all)

8:57 so (defroutes routes (GET "/show_bananas" [] (bananas-controller) :show-bananas) might be something you could hack

8:57 r4vi: bja: playing with it in the repl now

8:57 bja: adn then have a (url-for :show-bananas)

8:58 but the fill-in ability or something like "/foo/:bar/:quux"

8:58 would probably either be purely positional or kw-based

8:59 and you probably couldn't easily handle "/foo/:bar" and "/foo/:bar/:quuz" with the same name of :foo-bar-route

8:59 which is otherwise something I might do (in say Django's url routing system)

8:59 r4vi: bja: I think I would need to wrap defroutes

8:59 bja: yeah

8:59 wrap defroutes and register the extra argument into an atom

8:59 then provide some functions to lookup in the atom

9:01 but with a :foo-bar route defined as "/foo/:bar" you'd probably want some url-for to be like (url-for :foo-bar :bar 25)

9:01 or maybe (url-for :foo-bar 25)

9:02 being able to pass in :bar

9:02 justin_smith: r4vi: in general that is called reverse routing

9:02 it is supported by caribou (and the future replacement router for caribou, a standalone project called polaris)

9:03 reminds me I need to nag patchwork to get polaris merged, he said he wanted to be the one to do it...

9:03 r4vi: justin_smith: thanks, searching for reverse routing compojure gives us this https://groups.google.com/forum/#!topic/compojure/J-0KWht_-PM

9:03 which is almost exactly what bja is describing

9:04 justin_smith: we gave up on compojure because it was so macro centric, and we wanted to generate routes from data structures (in particular data structures coming from the db, so the cms could control and create routes in the app)

9:06 r4vi: "I think I would need to wrap defroutes" - thats when you start feeling the growing pains of compojure imho

9:07 https://github.com/caribou/polaris <- I am one of the designers, but that is not the only reason I really like it for routing

9:08 very edn-centric

9:08 r4vi: very nice stuff with the nested route definitions

9:09 justin_smith: and notice the reverse routing demo at the bottom of page

9:10 r4vi: caribou looks cool too, Django inspired?

9:11 justin_smith: we definitely took some ideas from django

9:11 it started as a php app for rapid webapp deployment

9:11 that was hard to maintain, so they upgraded to ruby

9:11 (RoR I think)

9:12 then that didn't scale performance wise, so they upgraded to clojure

9:12 then I joined

9:12 maybe some day we will upgrade to Haskell or something, but that would make me sad

9:35 gfredericks: (def rails (/ (+ php clojure) 2))

9:35 mdrogalis: Heh.

9:44 justin_smith: hah

9:45 on further consideration, I think mentioning the previous implementation stacks does caribou a disservice

9:51 wink: why? not starting from scratch but learning from your errors is good

9:52 clgv: (inc gfredericks)

9:52 lazybot: ⇒ 33

9:53 clgv: :P

9:53 (inc 42)

9:53 lazybot: ⇒ 3

9:53 clgv: :D

10:02 wei__: java.jdbc question. if I have a structure like this: ["INSERT INTO tbl (name, desc) VALUES (?, ?)" "bob" "hello"], what function do I call to run the insert and return the result?

10:08 arcatan: wei__: clojure.java.jdbc/query

10:09 wei__: oh, I thought query was just for SELECTs for some reason

10:10 arcatan: oh, hmm. maybe you need to use jdbc/execute!

10:52 justin_smith: db-do-commands / db-do-prepared

10:54 db-do-prepared is preferred if you have many insertions with that same structure, just different parameters

10:57 also consider insert! if you would prefer to provide a map from columns to values

11:45 sritchie: SegFaultAX: I did see that talk, it was great

11:46 that clearly seems like the way to go

11:53 jtoy: do libraries have access to their own resources directory? and if they do, can I reference them on the command line? I have a python script i want to call from my library

11:54 fakedrake: hello

11:55 coventry: jtoy: What does the script do?

11:55 makkalot: hi, i want to get fully qualified name of some variable in clojurescript, is there a way to do that ?

11:55 fakedrake: I have a vec of pairs [regex func] and I want to make a function that will run func depending on which regex is matches a given

11:55 string

11:55 is there a good built in for that?

11:56 jtoy: coventry: its a python machine learning script i wrote

11:56 justin_smith: jtoy: in a library it will be accessible as a resource inside the jar

11:56 bodie_: Does anyone have any thoughts on whether Clojure and Go are competitors, and if so, what merits are brought by each?

11:56 * bodie_ hides

11:56 jtoy: its just reads from STDIN and outputs to STDOUT and my clojure code needs to capture that

11:57 justin_smith: (spit (slurp (io/resource "filename")) "file-name-on-disk")

11:57 or maybe I have those spit args reversed

11:57 jtoy: justin_smith: I see, so I need to do that, thanks

11:57 justin_smith: be sure that the destination file is writable - in some environments the current working directory may not be writable by your process

11:58 this has bitten me in the ass before (inside tomcat)

11:58 jtoy: justin_smith: thx, I will try to use tmp for now to be safe

11:58 justin_smith: (spit "file-name-on-disk" (slurp (io/resource "filename")))

11:59 I had the args reversed

11:59 stompyj: is there a "preferred" way of handling configuration of env vars for web apps?

11:59 justin_smith: also the path will be relative to your resource-path

11:59 stompyj: you can access them directly with (System/getenv "env-key")

11:59 scriptor: hi, got a question about lazy seq implementation

12:00 justin_smith: stompyj: I sometimes find my self having to run (System/getenv "PWD") in my nrepl in emacs to remember which one it is

12:00 scriptor: since technically forcing a lazy seq does mutate the actual object, how is this reconciled with also keeping them functional/persistent

12:00 stompyj: justin_smith: right, but I meant, per environment variables, meaning, I have a set of AWS credentials for development, a set for staging, and a set for prod, etc

12:01 scriptor: is this sort of mutability considered okay?

12:01 stompyj: I just wondered if there was a community practice around that

12:01 or if it's just a "make it work" situatin

12:01 justin_smith: stompyj: with caribou we have an "environment" key in the env, and use that to decide which edn file to slurp for config

12:01 well read, but you get the idea

12:02 stompyj: ahhh nice

12:02 jtoy: i use APP_ENVIRONMENT

12:02 justin_smith: jtoy: that sounds much more professional

12:02 stompyj: justin_smith: I wanted to use caribou, but this app is so simple

12:02 I couldn't convince myself it was justified

12:02 it looks awesome

12:02 justin_smith: heh, yeah, I am working on making caribou more modular, pulling in fewer default dependencies so it makes more sense for simpler stuff

12:03 (while keeping it easy to pull in the more elaborate stuff if it is needed)

12:03 thanks :)

12:03 stompyj: justin_smith: where do you store the production env vars so it doesn't get stored in git/mercurial?

12:03 justin_smith: you mean the credentials?

12:03 stompyj: justin_smith: yeah, this is just compojure + liberator as a fancy proxy into mongo

12:03 :slamdunkL

12:03 :slamdunk:

12:04 justin_smith: I have a lib (blackbox) using my cryptlj lib that is still in the works for storing edn in aes128

12:04 currently we don't have something nice and sane, sad to say

12:05 stompyj: no worries

12:05 justin_smith: the hard part is convincing everyone to adapt to the encrypted workflow

12:05 if the security is a hassle, it just gets worked around in insecure ways, lose/lose

12:05 stompyj: yeah

12:05 coventry: fakedrake: http://clojure.org/multimethods

12:06 justin_smith: stompyj: I am working on a plugin system that will help address above mentioned complexity and size of caribou, and also make it easy to drop in the encrypted credentials in an existing app with minimal hassle

12:06 seangrove: SegFaultAX: What talk did you recommend to sritchie?

12:07 stompyj: justin_smith: excited to check it out

12:07 justin_smith: https://github.com/noisesmith/cryptlj - this is the underlying convenience lib for the encryption

12:07 https://github.com/noisesmith/cryptlj/blob/master/src/cryptlj/disk.clj the api is pretty simple

12:08 thin wrapper on the java rigamarole

12:09 the leiningen api is still unstable, fyi

12:11 coventry: seangrove: Pretty sure it was a conj talk titled "logs as data."

12:11 jjl`_: hi all. i've got this bizarre thing going on in my test suite where i'm comparing two maps with =. apparently both (is (= a b)) and (is (not (= a b))) pass. however, if i make a minor modification to the map, one of them starts failing as i would expect. adding prn calls shows that they're both having different values. does anybody have any idea what might cause this?

12:12 llasram: jjl`_: Can you produce a minimal example map?

12:12 The obvious thing to my mind would be adding to the map objects which don't adhere to the .equals contract

12:13 jjl`_: the thing causing it is adding a key to the second map that isn't in the first map which = nil

12:13 i'm trying to create a reduced case

12:13 llasram: You have non-nil objects which are `=` to nil?

12:14 jjl`_: the key does not exist in the first map. it is nil in the second. apparently they are both equal and not =

12:15 justin_smith: jjl`_: that surprises me

12:15 jjl`_: it surprises me too. they can't be both equal and not equal

12:15 gfredericks: as described this shouldn't have anything to do with the behavior of =

12:15 justin_smith: are you sure it isn't something like (is not (= a b))

12:15 gfredericks: as long as it''s deterministic

12:16 since he just passes it to not

12:16 Raynes: bitemyapp: Go.

12:16 The programming language.

12:16 justin_smith: or (is = a b) always returns true

12:16 seangrove: coventry: Ah, I liked that one a lot. Too bad it never got much traction inside Heroku :P

12:16 gfredericks: so justin_smith's guesses seem a lot more plausible

12:17 jjl`_: oh nevermind, it was an extra pair of parens, not a missing one. i'm just blind this afternoon apparently

12:18 sorry for the confusion

12:18 gfredericks: ,(deftype Foo [] Object (equals [this other] (zero? (rand-int 2))))

12:18 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

12:18 justin_smith: gfredericks: lol

12:19 gfredericks: ~sanbox

12:19 clojurebot: I don't understand.

12:19 fakedrake: coventry: very interesting but i do not thing multimethods are suitable, I will have to write tha iterating function as a dispatch fun

12:19 jjl`_: i'm surprised = tolerates only having one arg actually

12:20 justin_smith: jjl`_: check this out

12:20 ,(= Double/NaN)

12:20 clojurebot: true

12:20 justin_smith: mindblowing

12:20 ,(= Double/NaN Double/NaN)

12:20 clojurebot: false

12:20 justin_smith: as expected

12:21 amalloy: jjl`_: (apply = coll)

12:22 "are all elements of this collection equal?"

12:22 should work for one-element collections

12:22 jjl`_: ah, i suppose that's a fair enough use case

12:22 amalloy: otoh it should *also* work for empty collections, and doesn't iirc

12:22 &(apply = nil)

12:22 lazybot: clojure.lang.ArityException: Wrong number of args (0) passed to: core$-EQ-

12:23 jjl`_: of course every time you design for one use case, you're trampling on another :)

12:27 amalloy: feel free to show a use-case that is "trampled on" by having (=) return true instead of throwing an exception

12:28 jjl`_: i was talking more about the one arg part than the 0 arg parts really

12:41 danneu: ,(-> 1)

12:41 clojurebot: 1

12:41 danneu: ,(->> 1)

12:41 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$--GT>

12:41 danneu: y?

12:48 TimMc: ,(macroexpand-1 '(->> 1))

12:48 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$--GT>

12:48 llasram: danneu: Implementation quirks

12:49 TimMc: and poor base case coverage in clojure.core -.-

13:04 Bronsa: TimMc: danneu that's going to be fixed in 1.6.0 though

13:06 amalloy: ,'(->>) ;; hiredman, any plans to fix the macroexpander?

13:06 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$--GT>

13:08 TimMc: Where is "--GT" coming from?

13:09 coventry: TimMc: Is that an incomplete munging of ->> ?

13:10 TimMc: Oh, yeah.

13:10 demunging, actually

13:10 ->> munges to __GT__GT_

13:11 and that is incorrectly split on the second __ and demunged to --GT

13:14 hiredman: amalloy: I don't have any plans at the moment, I imagine the issue is the sandbox macroexpands everything ignore quotes, looking for bad forms

13:14 amalloy: hiredman: yes, that is the issue

13:14 you can have lazybot's macroexpand-most, if you want

13:14 or i guess it's in clojail, not lazybot

13:14 hiredman: I may just drop all of that given that the sandbox is in an isolated classloader and the sandbox is running in a chroot in another process

13:14 and the classloader is thrown away every 10 minutes anyway

13:15 coventry: riddley.walk has a pretty complete static macroexpand-all.

13:16 amalloy: coventry: why implement that, given that clojure.tools.macro/mexpand-all exists?

13:25 hiredman: the actual issue seems to be the 1.6 snapshot clojurebot had didn't have the fix for ->> in it

13:26 coventry: amalloy: My reason for rejecting it a while ago is that it reportedly doesn't deal correctly with &env, but maybe that's not relevant here. http://sgeo.tumblr.com/post/37646341234/clojure-macroexpansion

13:26 (Plus, riddley's not mine, anyway.)

13:52 danneu: How can I clean up nested `when-let`s? Here they are in a route: https://gist.github.com/danneu/7895990

13:53 One year of Clojure and this is my best right here folks

13:53 Raynes: Great Scott!

13:54 amalloy: danneu: i mean, there's nothing *too* terrible about that

13:54 technomancy: one let + when/and

13:55 amalloy: technomancy: i don't think that works very well when he depends on previous values?

13:55 danneu: many people have written a macro (when-lets [x foo, y bar] ...), though it's not fabulous

13:55 technomancy: oh sure

13:56 Raynes: Yeah, I can't think of tons of prettier ways to rewrite this.

13:56 amalloy: Raynes: switch to haskell, ???, profit

13:56 mdrogalis: What happens if a nil flows into one of the deeper functions, danneu?

13:56 amalloy: dat Maybe comprehension

13:56 tbaldridge: use a macro?

13:57 danneu: mdrogalis: nothing bad. i guess the idea was to short-circuit early

13:58 mdrogalis: danneu: If those functions fail hard and throw an exception, you can just use let's with some detatched error handling from Dire.

13:58 I've seen a few people use it to evade monads.

13:59 tbaldridge: danneu: here's a macro that should allow you to collapse all the when-lets into a single when-let*: https://gist.github.com/halgari/7896099

14:00 stuartsierra: danneu: depending on the use, `some->` may suffice

14:00 mdrogalis: The macro king.

14:00 danneu: cool. thanks team

14:02 tbaldridge: to be honest, I'm not completely sure why the standard when-let only supports a single binding.

14:02 stuartsierra: This has come up on the mailing list before.

14:03 TimMc: With explanation, or just speculation?

14:03 coventry: "lein repl" was failing for me with "clojure.tools.nrepl.transport.FnTransport cannot be cast to clojure.tools.nrepl.transport.Transport". Seems I've managed to heisenbug the failure away by touching one of the files involved. Anyone know what the cause might have been?

14:03 stuartsierra: If I recall, I think it came down to semantic ambiguity.

14:03 amalloy: stuartsierra: i think it's only ambiguous if you try to do it for if-let, not for when-let

14:03 stuartsierra: amalloy: That may have been the justification, for all I can remember.

14:03 amalloy: but maybe not; i might have been arguing semantic ambiguity myself last time

14:04 stuartsierra: I don't have a strong opinion. `some->` fulfills the most common use case.

14:05 danneu: clojuredocs.org could use a some-> example

14:06 oh yeah, it stopped at 1.3

14:09 cldwalker__: danneu: your example updated with some-> https://gist.github.com/cldwalker/7896195

14:14 coventry: cldwalker__: That's slightly different semantics, though, in that it's hitting the db for the story before the chapter slug has been validated.

14:41 danneu: cldwalker__: thanks

14:42 bitemyapp: danneu: and

14:43 danneu: actually wait, some-> is better.

14:43 n/m

14:55 tuddman: I built a clojure library to "dynamically" push/pull/read data in and out of excel - https://github.com/tuddman/clj-dde

14:56 it's early stage. if anyone needs that sort of thing, have at it. feedback welcome.

14:56 bitemyapp: tuddman: sounds pretty cool, announce it on the ML if you haven't!

14:57 tuddman: bitemyapp: not on said ML. (new to clojure)

14:57 bitemyapp: tuddman: the Clojure mailing list.

14:59 technomancy: "SML is the standard ML!" (to the tune of "ed is the standard editor!")

15:01 bitemyapp: technomancy: lol Bob Harper

15:02 ucb: bitemyapp: http://i.imgur.com/CgfWMA2.jpg

15:03 technomancy: http://www.georgehart.com/bagel/bagel.html

15:04 bitemyapp: technomancy: this explains why jewish people are well-represented in mathematics. They get topology lessons on Saturday night.

15:05 rlb: Is there a ring option to disable the non-ssl listener?

15:05 bitemyapp: ucb: you've found a greater trull than me. congrats.

15:05 rlb: huh?

15:06 hiredman: rlb: last I checked the ring-jetty-adapter unconditionally enables it

15:06 rlb: bitemyapp: i.e. if I say :ssl-port 4443, "lein ring server" will set up https on 4443, but it still accepts non-https connections on 3000 (or whatever).

15:07 I'd like to just disable anything other than ssl-port.

15:07 hiredman: it is important to distinguish between ring the library of stuff, ring the spec, and ring adaptors

15:07 rlb: And it doesn't appreciate setting :port to false ;>

15:08 hiredman: ok, right -- I probably meant ring-jetty-adapter.

15:08 hiredman: rlb: so in case no one has had this talk with you yet, don't use lein to run services out of a git checkout

15:09 so lein ring server listening on the extra port for development, who cares

15:09 rlb: hiredman: thanks, no one has, though in this case, I'm just playing around.

15:10 technomancy: SSL termination in jetty itself is mildly sketchy

15:11 hiredman: now for actually deployment you'll either do like technomancy recommends, and embed ring's jetty stuff in your app, and you still won't be able to disable listening on the non-ssl port, or you'll package as a war, and you will have your own jetty config to do whatever you want with

15:11 technomancy: in what way?

15:11 technomancy: hiredman: you want your JVM running as root to sit on 443?

15:12 hiredman: technomancy: that assumes it will be an external services that needs to sit on the well known port

15:12 stuartsierra: Alternately, JSVC / Apache Commons Daemon lets you bind to a system port and then drop privileges like a good Unix process.

15:12 technomancy: true; for specialized cases it's fine

15:12 it just sets off my "look out" pattern match

15:13 stuartsierra: the jvm and "like a good Unix process" also sets off my "sketchy" pattern match

15:13 but who knows; maybe it's fine

15:13 stuartsierra: haha

15:15 rlb: So it isn't really immediately relevant, but I've seen the recommendation to just use apache/nginx as a proxy for https. Is that a preferred approach?

15:15 justin_smith: yeah, it's a lot easier

15:15 and you want them in front of the app for security reasons too

15:16 hiredman: that is a common setup, but it is less flexible, for example if you want to be cool and do client side certificate auth

15:18 justin_smith: apache and nginx support that don't they? or are they just less flexible in their support?

15:19 rlb: hiredman: so an alternative would be to run the app as non-root, but use stuartsierra's suggestion (or similar) to handle the privileged port?

15:19 * rlb is mostly just curious atm

15:19 stuartsierra: I think the most common technique is to reverse proxy with Apache or nginx.

15:19 hiredman: justin_smith: it depends if you want to do it at the app layer

15:20 rlb: *shrug* it is tradeoffs all the way down

15:20 justin_smith: right, of course

15:22 sveri: hi, i have the following clojurescript code: http://pastebin.com/8JyRDGvV but when i open a page with the built js i get the following error in the js console: Error: Cannot merge $e into node of different type

15:22 any idea what is wrong there?

15:22 bitemyapp: rlb: that's not Ring, that's lein ring.

15:22 rlb: that's also Jetty specific.

15:23 pbostrom: "don't use lein to run services out of a git checkout" <- what is the issue with this?

15:26 goraci: hi what the best way to refer function from other namespace ? require or use ?

15:27 stuartsierra: goraci: `require` always and forever, optionally with `:as` or `:refer`

15:27 seangrove: goraci: Always require

15:27 sveri: Haven't used c2 at all, sorry - the code looks pretty reasonable

15:28 goraci: stuartsierra: in what case use preffered ? for what ?

15:28 bitemyapp: stuartsierra: protocols as a halfway step to ML functors. Thoughts?

15:29 coventry: goraci: use (use) for as a convenient way to grab stuff at the repl.

15:29 s/for//

15:29 stuartsierra: bitemyapp: that's basically what I Do

15:30 bitemyapp: stuartsierra: my suspicions are validated. Thanks.

15:30 wanted to make certain I was seeing the bigger picture properly.

15:32 coventry: That nrepl middleware error I was asking about was caused by (:require :reload)ing [clojure.tools.nrepl.transport :as t] or [clojure.tools.nrepl.misc :as m]

15:36 jcromartie: so apparently you can have a protocol function and a defn in the same namespace with different arity?

15:36 could that potentially confuse things? it seems to work in my tests

15:37 stuartsierra: jcromartie: that won't work in general

15:37 jcromartie: define "in general", because in this particular case it works :)

15:37 (defprotocol Herp (derp [x y])) (defn derp [x] (derp x 42))

15:38 stuartsierra: The later `defn` is overwriting the protocol function.

15:38 It might seem to work in a few odd cases.

15:38 But it definitely isn't intended to work that way.

15:39 jcromartie: hm

15:39 yeah I didn't think so (this was someone else's code)

15:50 technomancy: oh man I hadn't thought of client certs for jetty doing SSL

15:50 I would heart that so much

15:52 sveri: seangrove: thats what i was thinking too :D

15:57 brainproxy: dnolen: have I possibly found a bug in clojurescript's range, or am I misunderstanding something:

15:57 https://gist.github.com/michaelsbradleyjr/7899410

16:01 gfredericks: jcromartie: stuartsierra: might that work because the the compilation of (derp x 42) has some inlining or something that isn't sensitive to the var being redefined?

16:01 jcromartie: yeah but I wouldn't want to rely on that for sure

16:01 gfredericks: oh certainly; presumably any further references wouldn't work

16:02 jcromartie: somehow, it works, but I'll be refactoring it

16:02 the other guy on the project is a Clojure newb

16:02 but he picked it up amazingly well

16:02 nothing can phase him

16:03 or is that faze

16:03 hm, yes, it's "faze"

16:03 :) gotta love English

16:10 cored: hi

16:10 dnolen: brainproxy: a more informative paste that actually includes the output would be helpful :)

16:10 cored: is there a function that tells me the type of a value?

16:10 something like (is-a?

16:10 dnolen: ,(type [])

16:11 clojurebot: clojure.lang.PersistentVector

16:11 brainproxy: dnolen: alright, wasn't sure if you could plop it into a repl

16:11 will improve it

16:12 cored: dnolen: thanks

16:13 noprompt: dnolen: this pure business is rocking my wold right now.

16:13 dnolen: noprompt: :)

16:14 noprompt: I'm cooking some stuff up, it's a bit slow going though because I'd like to get some enhancement into CLJS before I write up a post

16:15 noprompt: dnolen: did you see those little macros i put together around it? well, that plus a little hiccup.

16:15 cored: Applies fn f to the argument list formed by prepending intervening arguments to args.

16:15 that's is kinda confusing

16:15 can somebody explain it to me please

16:15 I think that what is says is that I can apply a function to each element of an list, is that correct?

16:16 hiredman: it doesn't say each anywhere

16:16 noprompt: dnolen: looking forward to that new version. i'm using react.min.js right now to avoid the closure compiler complaints. :|

16:16 coventry: ,(apply (fn [& args] args) 1 2 3 4 (range 5))

16:16 clojurebot: (1 2 3 4 0 ...)

16:16 coventry: ,(-> (apply (fn [& args] args) 1 2 3 4 (range 5)) str)

16:16 clojurebot: "(1 2 3 4 0 ...)"

16:16 coventry: ,(-> (apply (fn [& args] args) 1 2 3 4 (range 5)) pr-str)

16:16 clojurebot: "(1 2 3 4 0 ...)"

16:16 coventry: bah

16:16 cored: hm

16:16 dnolen: noprompt: yeah it's coming - just need to sort out this macro enhancement and I want to fix an issue with resolving namespaces

16:17 justin_smith: cored: also, for is-a? you may want implements?

16:17 cored: coventry: still don't get it

16:17 justin_smith: thanks

16:17 dnolen: noprompt: yes the hiccup macros are pretty cool - want to get god looking api down that's just based on functions first though

16:17 justin_smith: wait, it isn't implements?

16:18 noprompt: dnolen: basically that's what i did. i ditched the macro version in favor of a minimal function based version (no css selector style tag names).

16:18 justin_smith: ,(instance? clojure.lang.ISeq ())

16:18 clojurebot: true

16:18 justin_smith: that's the one, instance?

16:18 cored: justin_smith: oki

16:18 so if I have a (range 4)

16:18 coventry: cored: (apply f a b c [d e f]) is the same as (apply f [a b c d e f])

16:18 cored: and I want to use each value inside it

16:19 I thought that I could use apply

16:19 coventry: cored: That's what that docstring means for example.

16:19 justin_smith: that helps if you want to check for protocol / interface compatibility

16:19 clojurebot: excusez-moi

16:19 noprompt: dnolen: but i'm interested to see what you come up with.

16:19 cored: but what apply does is to stick the first argument as a front of the second which is a list and then evaluating the entire thing, correct?

16:20 dnolen: CLJS feedback on this enhancement *greatly* appreciated - http://dev.clojure.org/jira/browse/CLJS-721

16:20 coventry: ... and both forms give the same result as (f a b c d e f)

16:20 dnolen: trying to figure out what to support as far explicitly including macros stuff in one ns spec

16:21 brainproxy: dnolen: okay, I reworked my comments around the output (included in the gist) that I'm seeing in my browser's console

16:21 https://gist.github.com/michaelsbradleyjr/7899410

16:23 seangrove: dnolen: This is to get away from having a (:require ...) and (:require-macros ...) when they come from the same ns?

16:23 dnolen: I'm thinking about leaving the enhancement out of :use since you really only need :require

16:23 seangrove: yes

16:23 so currently I'm thinking :require should support :include-macros true, and :refer-macros [...]

16:23 and no support for this in :use

16:25 seangrove: :include-macros would bring in the macros but keep them namespaced (or aliased in the case of an :as), and :refer would drop the ns prefix?

16:25 noprompt: dnolen: oh that would be awesome.

16:25 dnolen: brainproxy: looks like a bug, please file a ticket, thanks

16:25 seangrove: exactly

16:26 seangrove: dnolen: Not a huge fan of stuffing more flexibility into the ns form, but that does what I would expect it to. Certainly straightforward/legible enough.

16:27 brainproxy: so basically you would have .cljs and .clj files side by side?

16:27 seangrove: technomancy: Was it you that had a patch to make namespace immutable with functional transformations?

16:27 brainproxy: i.e. with the same name other than the ext

16:28 dnolen: seangrove: agreed, but I think think wanting to keep the two same is very desirable because of the symbol resolution issues otherwise

16:28 seangrove: definitely open to better ideas if anyone has them, but this seems to cover the use cases and it isn't too verbose

16:29 and implementation is straightforward

16:29 tbaldridge: dnolen: so that would only pull in macros from that ns, or macros and fns?

16:29 technomancy: seangrove: no, but I was following up on some of the ancient discussions proposing to do so

16:30 dnolen: tbaldridge: well you can load fns from a macro file in CLJS

16:30 s/can/can't

16:31 tbaldridge: this is just sugar what I'm proposing will expand in to the base ns spec DSL

16:36 noprompt: dnolen: i like this idea. it seems weird right now to (:require [x :as x]) and then (:require-macros [x :refer [y]]) but it doesn't bother me *that* much.

16:37 dnolen: noprompt: yeah that case is less obnoxious, but that's not true when you want to generate a whole bunch of inlining macros that correspond to functions ala cljs.core arithmetic operators

16:38 so that why I'd like to see (:require [reactjs.dom :as dom :include-macros true]) for example

16:38 noprompt: dnolen: what are inlining macros?

16:38 dnolen: then all dom/foo calls inline into direct React calls, but you still get all the functional goodness

16:39 noprompt: ah

16:39 dnolen: noprompt: macros and fns can have the same name in ClojureScript unlike Clojure

16:39 this is why you aren't paying function call overhead for basic stuff like array access, array length, arithmetic etc

16:40 noprompt: dnolen: maybe a bit off topic but has anyone come up with an idea for :refer/:rename?

16:40 dnolen: or is that to hairy?

16:40 dnolen: noprompt: :refer is already supported, patch welcome for :rename

16:42 seangrove: technomancy: Someday, someday....

16:46 tonie_: has anyone used clojurescript in a production environment? care to share your experience? I'm looking to build a new web application that is to be a single-page application

16:46 trying to decide if i should write the application in clojurescript or javascript/angularjs

16:48 marcopolo2: tonie_: I've been rewriting cryptic.io in clojurescript

16:48 noprompt: dnolen: have there been any suggestions?

16:48 dnolen: noprompt: there have not

16:48 bitemyapp: marcopolo2: this is a what?

16:48 marcopolo2: I have to deal with webworkers, along with all the traditional worries in big client side apps

16:49 noprompt: dnolen: wow. that's surprising. seems like that'd have been a pain point for someone by now.

16:49 marcopolo2: bitemyapp: ?

16:49 tonie_: The original prototype was built with backbone

16:49 bitemyapp: marcopolo2: what's cryptic.io?

16:49 dnolen: noprompt: I never use rename, mostly because I rely on :as

16:49 noprompt: but rename would be nice if just to be consistent

16:50 marcopolo2: bitemyapp: online storage, where everything is encrypted in the browser

16:50 bitemyapp: marcopolo2: client-side encryption? phew.

16:50 tonie_: margopolo2: i'm cehcking out the site now. very interesting. did you use any frontend framework?

16:51 bitemyapp: marcopolo2: so nobody on the team has a background in cryptography?

16:51 nDuff: tonie_: I have an app using clojurescript that's been humming along in production for upwards of a years -- a JIRA plugin; the big pain point there was playing nice with JIRA's own javascript, which stomps on the goog.string namespace and does other such nastiness.

16:51 marcopolo2: tonie_: The site that's live is using backbone, you can find the initial work of cljs in the github repo

16:51 bitemyapp: We aren't making any new crypto schemes

16:51 nDuff: tonie_: ...but modeling state with atoms &c. made things quite pleasant; I'd do it again.

16:52 Cr8: oh gods

16:52 marcopolo2: bitemyapp: just using the good ol' CTR block ciper with AES-256

16:52 Cr8: MAC'd?

16:52 seangrove: nDuff: Did you not use advanced compilation/munging?

16:52 nDuff: seangrove: I did.

16:52 marcopolo2: tonie_: I really like pedestal app, it makes it easy to focus on one part of the application at a time

16:52 bitemyapp: marcopolo2: but...client-side?

16:52 Cr8: Good source of randomness for nonces?

16:53 seangrove: nDuff: How did JIRA manage to hurt your namespaces then?

16:53 bitemyapp: Cr8: /dev/urandom

16:53 seangrove: Also, how did you work around it?

16:53 Cr8: bitemyapp: not in JS!

16:53 bitemyapp: Cr8: WHICH IS MY POINT

16:53 marcopolo2: bitemyapp: I actually fixed Mega's own crypto :P

16:53 bitemyapp: marcopolo2: you can't fix something that doesn't have reliable access to /dev/urandom.

16:53 nDuff: seangrove: Google Closure's namespace loading appeared to look at whether an unmunged name exist and refused to load.

16:53 tonie_: marcopolo2: thanks for the advice. i looked at pedestal. the relevence team is obviously awesome. i was INTIMIDATED by the tutorial/documentation. i think i will give it another go

16:53 bitemyapp: this is why people can't even be trusted to deploy existing crypto, let alone implement new schemes.

16:54 marcopolo2: bitemyapp: browser's have window.crypto.getRandomValues

16:54 tonie_: nDuff: thank you for the advice. i'll keep that in mind

16:54 bitemyapp: marcopolo2: which provides insufficient entropy guarantees.

16:54 nDuff: seangrove: ...I ended up just temporarily removing their goog.string before loading the cljs-generated .js.

16:55 marcopolo2: tonie_: the tutorial is really long, but you'll learn alot. They are redoing a lot of stuff, so you might want to wait for the new version to come out?

16:55 bitemyapp: marcopolo2: did you guys consult with anybody that works in cryptography before building this?

16:55 anybody credible*

16:56 tonie_: marcopolo2: the concepts are really interesting. the idea of writing a frontend application without getting bogged down in statefulness is enough to sell me on it

16:56 marcopolo2: bitemyapp: there is no reason we couldn't have people import their own generated private keys

16:56 bitemyapp: for the truly paranoid on the browser's random values

16:57 Apage43: you still need a good nonce for every message you encrypt

16:57 seangrove: nDuff: Ah, that's a bit rough. Wish you could prefix the namespaces so multiple apps/versions of closure could co-exist

16:57 marcopolo2: Apage43: that's right

16:58 seangrove: tonie_: Pedestal is significantly different from pretty much any other approach on the web right now - some libraries like React are independently converging on similar solutions to some of the problems though. Just expect the painful newb feeling for awhile with it.

16:58 Apage43: also is the message MAC'd?

16:58 file body, w/e

16:58 marcopolo2: bitemyapp: Apage43 Cryptic still has a bit to go before being open to the public, so it's free to get shaped by anyone

16:58 Apage43: uses CCM

16:58 Apage43: ah

16:59 i read CTR earlier

16:59 marcopolo2: well CTR is a part of CCM

16:59 tonie_: seangrove: looking forward to trying it out. i'll have some free time over holiday break. i've heard good things about it

16:59 marcopolo2: but you are right, I should have said CCM

17:00 nDuff: ...what's the status of pedestal 0.3?

17:01 marcopolo2: tonie_: The google group for pedestal is pretty helpful, Ryan will usually answer questions daily

17:01 tonie_: marcopolo2: good to know. will join that now

17:05 marcopolo2: bitemyapp: I can see how it could be a hard sell to trust a stranger with providing strong crypto; what would you like to see happen before you trust cryptic?

17:06 Cr8: if you take as given that the browser crypto is solid, we still have the issue that I *actually have to trust cryptic*

17:06 same as the lavabit problem, Just because you can't read my stuff now, doesn't mean the system can't change without me noticing

17:07 there's not really a good way around that in the browser though

17:07 tarsnap is an example of a service I *don't have to trust*

17:07 because given that I have a copy of their client that I trust, nothing they do on their end *after that* can compromise my data

17:08 marcopolo2: Cr8: yup. We have all client-side code open-sourced (given), and we have an extension that will verify the files returned from the server against their signed hashes on the open source repo.

17:08 Cr8: but with browser stuff, I download a new copy of the client every time I visit the page

17:09 marcopolo2: must also ensure that no code that wasn't there before is there, not just that the code that I had before hasn't changed; e.g. window.crypto = evilCrypto

17:09 marcopolo2: Cr8: the extension would prevent code that isn't on the repo from going undetected

17:10 and if the repo has it, then we are accountable to that. But, it can't happen without someone noticing

17:16 tomjack: https://www.refheap.com/d1266cb7e64bd92b31fa8d9c9

17:17 I wonder if LazySeq's equals could be better about noticing identity?

17:17 could/should

17:17 guess you can just seq both sides

17:18 ivan: what about NaNs!

17:18 Cr8: I'm wondering why that identical? returns true

17:18 ivan: NaNs prohibit equality optimizations everywhere

17:18 tomjack: :(

17:19 TimMc: &(map (memoize println) (repeat 32 Double/NaN))

17:19 lazybot: ⇒ (NaNnil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)

17:20 hyPiRion: hah, that's sort of funny

17:23 justin_smith: NaN NaN NaN NaN NaN NaN NaN NaN Batman

17:24 hyPiRion: ,(map print (conj (vec (repeat 16 (/ 0.0 0.0))) " batman "))

17:24 clojurebot: (NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN batman nil nil nil nil nil ...)

17:24 hyPiRion: yeah, you beat me to it

17:48 bitemyapp: marcopolo2: an indication that you worked with an actual expert

17:48 TimMc: &({Double/NaN 5} Double/NaN)

17:48 lazybot: ⇒ nil

17:48 bitemyapp: marcopolo2: instead of making the same mistakes every other non-crypto-expert makes

17:48 like trusting browser entropy.

17:50 TimMc: OK, what am I missing -- how does memoize not run println over and over?

17:51 amalloy: TimMc: you're passing it a Double-wrapped version of Double/NaN, which is pointer-identical to itself

17:52 &(let [x Double/NaN] (= x x))

17:52 lazybot: ⇒ false

17:52 amalloy: &(let [x (Double. Double/NaN)] (= x x))

17:52 lazybot: ⇒ true

17:52 TimMc: Oy vey.

17:52 bitemyapp: equality and identity are slip'ry

17:53 TimMc: I have a fun fixed point puzzle somebody posted on Twitter if you want :D

17:53 amalloy: you could use (repeatedly (fn [] Double/NaN)) instead of (repeat Double/NaN), and then memoize wouldn't "work"

17:53 TimMc: &(find (hash-map Double/NaN 5) Double/NaN) ;; and why does wrapping not happen here?

17:53 lazybot: ⇒ nil

17:53 amalloy: TimMc: you wrapped it twice

17:53 got two different Double instances

17:53 TimMc: Aha.

17:54 Same NaN, different NaN. But all NaNs are different, except when they're the same.

17:54 Very clear.

17:54 amalloy: i confess i would not have expected this behavior of memoize/NaN, but once you asked about it that was the only possible explanation

17:55 TimMc: So false is wrapped specially?

17:56 riley526: clojurescript

17:56 (woops, I meant to search, lol)

17:57 TimMc: Or... I guess every source of false (including the reader) is using Boolean/FALSE.

17:58 No, wait... Boolean/FALSE is an object, Double/NaN is a primitive.

17:59 * TimMc flips all the tables

18:00 amalloy: well java the language doesn't exactly need Boolean/FALSE as a primitive, since that's a keyword already

18:01 TimMc: Yeah, that makes "sense".

18:01 amalloy: heh, exactly

18:04 TimMc: bitemyapp: Hit me.

18:04 magnars: technomancy: since resources behave differently in Jars and on the file system, I would like to add a jar to the class path for testing purposes. Any way to do that with leiningen?

18:05 hiredman: magnars: say what?

18:05 technomancy: magnars: sure; just deploy it into file://$HOME/.m2/repository and add it to :dev :dependencies

18:06 hiredman: in what case do they behave differently?

18:08 jtoy: justin_smith: there is no navigation at http://caribou.github.io/caribou/docs/components.html

18:08 magnars: technomancy: then what about CI and other developers - would they have to manually deploy the same jar to their .m2 folders? Or am I looking at creating a nexus for my test jar?

18:08 technomancy: magnars: you can put your test jar on clojars

18:08 magnars: technomancy: oh, I would think that was rude somehow. :)

18:09 technomancy: there's tons of crazy stuff on clojars

18:09 musicalchair: let's say I have a classpath generated by a different build system and want to augment leiningens classpath with that.. possible? this is for internal prototyping. Importing the clojure dependency closure into the internal build system is prohibitively expensive for prototyping

18:09 TimMc: I backup all my music to Clojars under the guise of a templating library.

18:10 musicalchair: might be easier to go the reverse way

18:10 or just do it manually.. hmm

18:10 justin_smith: jtoy: "Documentation" is a hyperlink, though it should make itself more clear as such

18:10 bitemyapp: TimMc: map fst $ filter snd $ zip [2..] $ map (=='"') $ fix show

18:10 justin_smith: jtoy: in fact there are many links, they just don't highlight on hover

18:11 bitemyapp: TimMc: figure out what it does without running it.

18:11 jtoy: cool

18:11 bitemyapp: TimMc: hoogling is allowed.

18:11 magnars: hiredman: well, for one you can't do clojure.java.io/as-file on a resource in a Jar, but you can on one in the file system. But there's other quirks too, like when an input stream is opened. A file will open an input stream when you do openConnection, while a resource in a Jar will wait untill you do getInputStream.

18:11 TimMc: Oh, nope, don't know Haskell.

18:11 bitemyapp: TimMc: try!

18:11 TimMc: I think you can do it :D

18:12 justin_smith: jtoy: yeah, as far as I am concerned it should be more obvious what parts of the text are links

18:12 magnars: technomancy: thanks for the help :)

18:12 TimMc: Man, I don't even know the precedence rules.

18:13 technomancy: precedence rules are the worst =(

18:13 hiredman: magnars: ah, differences in the url handlers

18:14 technomancy: the part of my brain that stores precedence rules has been re-allocated to more important tasks, please try again later

18:15 justin_smith: in the crazy mirror world of #clojure lolparens becomes lolprecedence

18:15 TimMc: bitemyapp: something like (map first (filter second (zip (range 2 Double/POSITIVE_INFINITY) (map (partial = \") (fix show)))) ?

18:16 amalloy: bitemyapp: that's weird. i tried to do it in my head but i was quite wrong about what (fix show) would return

18:16 TimMc: yes

18:19 TimMc: bitemyapp: Got it.

18:19 technomancy: TimMc: can't you pass range a single arg?

18:20 TimMc: technomancy: Then it's an upper bound.

18:20 technomancy: oh gotcha

18:21 (drop 2 (range))

18:21 TimMc: hah

18:21 Oh, I like that.

18:21 technomancy: =)

18:21 TimMc: Now you're thinking with seqs.

18:22 bitemyapp: amalloy: fix show is pretty crazy.

18:22 TimMc: are you sure you have it right?

18:22 TimMc: No.

18:22 bitemyapp: nevermind, he got it.

18:22 well, mostly.

18:22 TimMc: I did have to play with show a bit to find out what the hell it was.

18:23 bitemyapp: show wasn't the tricky part for me, it was fix.

18:23 I understood fixed point functions but the implications for show confused me initially.

18:23 TimMc: I still don't know how fix is supposed to do that, but I just figured what it had to do.

18:24 bitemyapp: TimMc: non-strictness makes it work.

18:24 non-strictness lets you get intermediate results from infinite recursion invocations

18:25 almost like "reductions"

18:25 infinitely recursive*

18:25 TimMc: How does it know what to start with? Or is it that show can at least realize one character, so it doesn't need to?

18:25 bitemyapp: TimMc: you think that's weird, you should try a strange loop like loeb!

18:26 TimMc: Hmm, this can be done in Clojure, yes?

18:27 Cr8: is that because the result of show, being a String

18:27 the first outerly-applied show must return a result beginning with a \", so can just go ahead and do that based on that type, not needing the value

18:27 and so on

18:27 bitemyapp: TimMc: not properly, no.

18:28 you can only imitate or fake it.

18:28 TimMc: I think it's possible.

18:29 bitemyapp: TimMc: it's a matter of mathematical possibility

18:29 TimMc: anything you could come up with would be an imitation with different semantics.

18:29 TimMc: non-strict and lazy languages can express things that are non-terminating infinite loops returning nothing in strict semantics.

18:29 TimMc: With show: seq -> seq, and fix (seq -> seq) -> seq

18:29 bitemyapp: ...that's not the same thing at all

18:30 that's faking it with sequences.

18:30 TimMc: Fine. :-P

18:30 I just mean within the scope of this exercise.

18:31 I remember someone doing some knot-tying with seqs in this channel, let me dig it up.

18:31 bitemyapp: TimMc: fix of a function diverges if the function is strict in its arguments.

18:32 TimMc: ,(take 10 (let [p (promise)] @(deliver p (lazy-cat [1 1] (map + @p (rest @p)))))) ;; from hiredman

18:32 clojurebot: (1 1 2 3 5 ...)

18:33 dnolen: :include-macros and :refer-macros support in :require landed in CLJS master https://github.com/clojure/clojurescript/commit/de6ee41b3b0e26020e01b409f97e513bce87456d

18:34 bitemyapp: TimMc: that's not the same thing and you know it.

18:34 TimMc: Hmm, yeah, because map has to "participate" in the scheme.

18:34 bitemyapp: when you distort the semantics that much you might as well be writing C.

18:35 nifty though.

19:19 rkneufeld: nDuff: slow going. There has been little movement as we became very scattered after Conj and leading into holidays

19:28 ztellman: does anyone know how to make the cider repl history persist between sessions?

19:31 justin_smith: ztellman: set the file name

19:31 ztellman: justin_smith: ah, it's unconfigured by default

19:31 justin_smith: (setq nrepl-history-file "~/.emacs.d/nrepl-history.eld") ; the nrepl version

19:31 I assume s/nrepl/cider and all is golden

19:40 amalloy: ztellman: finally giving up swank?

19:41 ztellman: amalloy: I switched away while I was feverish and weak

19:41 I regret it already

19:49 amalloy: i'm kinda disappointed snackoverflow.com doesn't exist

19:50 hiredman: are you familiar with guthub.com?

19:50 amalloy: i have been there many times

19:51 hiredman: well, it is one of hte possible results from a snackoverflow

19:54 pjstadig: ah

19:54 snackoverflow

19:54 now there's a startup idea

19:59 justin_smith: snackernews

20:03 http://on.aol.com/video/snackoverflow-demo-at-hackathon-sf-2013-517925738

20:11 bitemyapp: swank :(

20:11 the cider stuff really just makes me more mad about having given up swank.

20:14 Bronsa: bitemyapp: I tried twice to transition from slime to nrepl.el/cider but after a couple of hours I had to switch back :/

20:15 ddellacosta: bitemyapp: why? what's bad about cider comparatively? I never got familiar with swank, which is why I ask

20:16 coventry: ddellacosta: Debugging facilities worked a little better in swank.

20:22 bitemyapp: "a little"

20:22 Raynes: bitemyapp: Down boy.

20:22 * Raynes stomps.

20:23 bitemyapp: Raynes knows my pet peeves.

20:23 arrdem: bitemyapp: oi. do you know of a reasonable lambda calculus monads paper?

20:23 Raynes: I'm all up in your psyche.

20:24 bitemyapp: arrdem: closer to type theory, algebra, and category theory.

20:24 arrdem: I don't think that's something you want to build up to from scratch from typed lambda calculus.

20:25 justin_smith: bitemyapp: how about a peano numbers based matrix algorithm?

20:25 lol

20:25 arrdem: bitemyapp: meh ok.

20:25 bitemyapp: arrdem: do you want to understand monads themselves or their relationship to other concepts?

20:26 arrdem: bitemyapp: I've been cramming typed lambda calculus all afternoon and I was hoping there was a reasonable mapping between the two

20:26 bitemyapp: arrdem: untyped or typed lambda calculus?

20:26 arrdem: practical use of monads is built on type deduction if you're not fucking insane.

20:26 arrdem: bitemyapp: typed. I said that.

20:27 bitemyapp: sorry, my eyes skipped it

20:27 arrdem: how close are you to something like System F or dependent types?

20:27 coventry: This early paper on monads has lambdas in it, but I wouldn't call it lambda calculus. http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf

20:27 It's a very accessible paper, though.

20:27 bitemyapp: arrdem: monads are higher-kinded types.

20:27 clojurebot: Titim gan éirí ort.

20:27 arrdem: coventry: okay yeah that's one of the things i'm reading.

20:29 bitemyapp: arrdem: monads are tacked onto pure typed lambda calculus but I'm not sure how much sense it makes without typeclasses and higher-kinded types.

20:29 or algebraic types

20:31 coventry: When you say cramming, do you mean for an exam?

20:31 arrdem: coventry: finals man

20:31 bitemyapp: arrdem: you can't possibly need monads for finals?

20:32 arrdem: bitemyapp: I'm in a programming languages class. false.

20:32 bitemyapp: you're not at the university of glasgow though

20:32 arrdem: UT Austin wishes it was UGlasgow

20:32 bitemyapp: arrdem: the most thorough-going way to comprehend is to just write code.

20:32 arrdem: or at least look at the monad laws

20:32 and understand them algebraically.

20:32 identity, bind, return.

20:32 arrdem: http://www.haskell.org/haskellwiki/Monad_laws

20:35 coventry: Good luck!

20:35 bitemyapp: arrdem: good luck. I'm available tonight if you need any help with monads.

20:38 arrdem: thanks guys.

20:49 Raynes: arrdem: They're mostly just burritos.

20:49 And monoids in the category of endofunctors (what's the problem?).

20:50 hyPiRion: arrdem: I know your pain, man. Good luck!

20:50 coventry: I thought monads were midgets working on dildos which they took out of boxes. http://www.chrisstucchio.com/blog/2013/write_some_fucking_code.html

20:51 Wadler says in that paper that category theory is completely unnecessary to understand monads-as-programming-construct.

20:52 But it might be necessary to the exam, I guess.

20:54 bitemyapp: monads are really simple...

20:54 just write the code

20:59 talios: coventry - is it wrong that in reading that post, my only question is - whats a rabbit? :p

21:01 and no, I don't really want an answer :)

21:02 arrdem: fukkit I'm just gonna get this to compile (http://www.haskell.org/pipermail/haskell-cafe/2006-November/019190.html)

21:03 coventry: talios: It depends on your values, I guess. That I didn't even notice that the first time I read it because I was laughing so hard is definitely wrong, though.

21:03 talios: heh

21:04 I wonder if an Applicative is analogous to a butt-plug.

21:05 No wait, I'm not wondering. no no no no no

21:21 dfuenzalida: Hi everyone

21:22 Shiro-Ichida: Hello.

21:22 dfuenzalida: can somebody help me with a ClojureScript and regex question?

21:22 TimMc: coventry: That's a pretty good blog post.

21:24 dfuenzalida: ...I'm trying to do text replacement using clojure.string/replace in ClojureScript code but it doesn't seem to work as in regular Clojure

21:26 TimMc: dfuenzalida: Regular expressions are different on different platforms. Maybe that's causing problems for you?

21:26 s/platforms/hosts/ or whatever

21:27 arrdem: Raynes: you aren't helping here mate

21:27 Raynes: arrdem: I'm doing my best.

21:27 <3

21:27 dfuenzalida: TimMc: It seems I'll switch to .exec instead, thanks!

21:28 arrdem: bitemyapp: associativity is just m >>= a >>= b === m >>= b >>= a, right?

21:29 bitemyapp: but that doesn't make any sense if you're going to overload >>= to achieve control flow

21:29 *control flow manipulation

21:29 coventry: TimMc: justin_smith linked it here a couple of days ago.

21:31 amalloy: arrdem: that's not associativity, that's commutativity (which monads don't have)

21:32 arrdem: amalloy: that makes sense... I guess I'm reading the associativity law wrong.

21:33 amalloy: ((m >>= f) >>= g) = (m >>= \x -> ((f x) >>= g)) is associativity, i think

21:35 coventry: I think there are friendlier pages to look at regarding the monad laws than the one bitemyapp linked.

21:35 In particular, http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure-programmers-part-2/ , which has the advantage that it's in a familiar languge. :-)

21:41 talios: without an equivalent to flatMap/bind I don't really see how you'd do monads in clojure, in any reallllly nice fashion. concat-map isn't quite.... the same.

21:42 ToxicFrog: Does clojure have a convenient wrapper around the Java sockets aPI?

21:42 talios: probably start with a Protocol with an implementation that uses concat-map tho

21:42 bitemyapp: arrdem: you can have commutative monoids! then they're abelian groups :D

21:42 * talios checks he's in #clojure and not #haskell

21:42 bitemyapp: ToxicFrog: the Java API is convenient.

21:43 talios: I brought #haskell to #clojure

21:43 talios: I'm infecting the minds here

21:43 arrdem: ~bitemyapp

21:43 clojurebot: bitemyapp is it amuses me to mock other peoples' gods

21:43 talios: bitemyapp - hah, Frege or die :)

21:43 ToxicFrog: bitemyapp: I try to avoid using Java IO because I can never remember what combination of *Readers, *InputStreams, and god knows what else I need, and in what combination, to actually get data out of the damn fd.

21:43 brehaut: bitemyapp: sorry to disappoint, but konrad hinsen and jim duey were doing it years ago

21:43 :P

21:43 talios: well, I'm playing with idris and its java backend currently

21:43 bitemyapp: talios: Frege is really neat, but if the choice is "or die", I'd go with Idris :P

21:43 talios: 'lo brehaut

21:44 brehaut: hi talios

21:44 talios: bitemyapp - I already have a fork of idris where I'm tinkering with improving its maven support

21:44 bitemyapp: brehaut: I'm fine with being the third wave. That's the one that usually wins right?

21:44 talios: why maven?

21:44 brehaut: bitemyapp: i just recalled third wave ska and third wave punk. i dunno about that ;)

21:44 bitemyapp: whoa careful, talios is a maven zealot

21:45 bitemyapp: brehaut: http://i.imgur.com/ONGuFw7.jpg

21:48 brehaut: kooky. maybe even a little bit ooky?

21:48 brehaut: bitemyapp: mostly im giving talios crap :P

21:48 bitemyapp: brehaut: you should tease smalltalk users instead

21:49 arrdem: bitemyapp: those still exist?

21:49 brehaut: its hard to say; they arent seen outside of their image

21:49 bitemyapp: arrdem: dude, my twitter is a fucking wasteland the last 48 hours

21:49 arrdem: of people using cockamamie dynamic languages defending their gods

21:49 * arrdem cackles

21:57 Bronsa: tools.analyzer.jvm succesfully analyzed the whole core.async source+tests

22:03 gdev: Has anyone used Clojure in a game jam? Chris Granger's component entity system looks promising but I'm targeting the UDOO

22:04 marcopolo2: gdev: UDOO?

22:06 ToxicFrog: Argh death to this entire API forever

22:06 gdev: Linux and arduino http://www.udoo.org/

22:07 ToxicFrog: I wanted to ditch Saturnine because it's kind of a pain to debug but honestly it's looking more and more like the best option

22:07 gdev: marcopolo2, basically need to target ubuntu 12

22:13 arrdem: Bronsa: friggin awesome!

22:16 gdev: ibdknox, for Chromashift you only had to write the system in pure javascript right? everything else was pretty clojurey

22:26 talios: bitemyapp - hah, I'm an ex smalltalk lover, frege lover, and maven zealot :)

22:26 * talios returns from picking his car up from service, good lord transmission fluid, a spark plug, and oil soon mounts up the $$$$ :(

22:27 talios: bitemyapp - hah, clojure isn't a cockamamie dynamic language? :)

22:28 bitemyapp: talios: one of the few well thought out ones.

22:29 talios: true, tho a few places could do with some more thought. it still has its fair share of wtf's in spots

22:29 few and fare between, but they're still there a bit

22:41 bitemyapp: talios: I'm genuinely curious, where does the passion for maven come from?

22:41 talios: I take it for granted, like running water and working indoor plumbing.

22:43 talios: bitemyapp - hah, I daresay there's little "passion" for maven :p However, it works - and for its issues, maven-release-plugin is probably the primary reason for sticking. Along with mutli-language projects, and distribution.

22:43 leon, sbt, gradle, all seem to fail on that front. or at least have n number of 1/2 baked custom solutions

22:49 lein even

22:49 mmm, ironically I just got asked to install leon on the build server so we can get some lein projects building

22:50 how does one install leon? :)

22:50 lein

22:50 stupid autocompleting irc client

22:50 correcting even

22:51 arrdem: bitemyapp: so after much pondering, several papers and some heated arguments with classmates monads are friggin easy.

22:55 bitemyapp: arrdem: good, now explain them to me.

22:56 talios: script

22:56 talios: well I just wget'd it and chmod+d it. now to work out how to get jenkins to use it

22:56 dsrx: a monad is like a burrito that doesn't leak its contents

22:57 Cr8: autocomplect

22:58 bitemyapp: dsrx: fuck off with the innuendo.

22:58 arrdem: bitemyapp: all you need is a type, a definition of return and bind over the type and however many monadic functions you feel are in order. you roll up function composition through the monad and then (eval) it whenever you start to care about the exact value or when the side-effects become meaningful.

22:58 dsrx: now i'm craving a burrito...

22:58 arrdem: getting not scared of >>= was the hardest part :P

22:59 dsrx: the thing i still struggle with with monads in haskell is using the *M (filterM, foldM, mapM) functions

22:59 bitemyapp: arrdem: cool. and you see the parallels to inversion of control right?

22:59 arrdem: this is why Async in OCaml is built on monads, they're inversion of control callbacks for the async semantics.

23:00 arrdem: also, monads don't need to have side effects

23:00 arrdem: they can just be a way to box up non-determinism in general.

23:01 dsrx: the identity monad is a trivial example of that

23:02 arrdem: I mean it really isn't a callback at that point, it's a >>= chained call forwards over Maybe or something else, right?

23:03 bitemyapp: arrdem: no, it's basically a callback.

23:03 arrdem: the difference is it's basically sequencing the chaining of the data from callback to callback when the IO is done and the data can be sent down the hole.

23:03 arrdem: they're not callbacks in the sense that you manually do CPS, but the monad is definitely hollywood style.

23:04 an event loop is managing the registered handlers in the monads

23:04 talios: does leiningen have any form of lifecycle?

23:07 bitemyapp: talios: waddat?

23:08 talios: a set of standard tasks to run, i.e. clean -> compile -> test -> install

23:08 bitemyapp: talios: it understands tasks dependency.

23:09 talios: it may - but what task to run :) that can change at whim per project

23:09 i.e. test vs expectations

23:09 "test" only runs some tests

23:09 I like expectations as a framework, but f***k - running your tests in the VM shutdown hook? what idiot dreamed up that idea

23:09 cockamamie I tell you :)

23:10 bitemyapp: yeah that's kinda dumb.

23:11 talios: took me ages to figure out why my CI builds weren't failing - as they technically weren't running tests that affected the exit code

23:11 gah

23:27 bellkev: Is it possible to include clojure libraries as compile-time-only dependencies in clojurescript projects? So that e.g. I can write a macro that compiles hiccup to strings at compile time?

23:30 technomancy: talios: the shutdown hook is pretty nutty; I think that's a ruby "innovation"

23:30 talios: go ruby!

23:31 arrdem: yeah ruby! eat that paint!

23:31 technomancy: you can add to lein's :prep-tasks, which all get called in sequence before any code gets eval'd

23:31 talios: weird - wonder why I disconnected there

23:31 technomancy: and you can shadow existing tasks with aliases to chains that include the original task

23:31 talios: technomancy - is that like a "default task set" that gets called if I just call "lein"

23:32 or, usable as

23:32 technomancy: talios: no; `lein` -> `lein help`

23:32 :prep-tasks is just "stuff that must run before the project is ready to eval any other code"

23:33 we're working on programmatic manipulation of project.clj for 2.4.0 but were blocked for a long time on a lossless reader

23:34 arrdem: technomancy: don't we have that in tools.reader? it seems like writing metadata selectively would be the harder problem.

23:35 xeqi: bellkev: does using the :dev profile do what you want?

23:35 technomancy: arrdem: AFAIK tools.reader does not preserve comments

23:35 arrdem: technomancy: I believe you are correct. or whitespace. interesting point.

23:35 technomancy: but we have sleight now

23:35 err

23:35 sjacket

23:35 eh

23:35 screw whitespace

23:36 arrdem: yes... but no. the indentation of comments is meaningful sometimes.

23:36 some MFST people I talked to had interesting comments about whitespace and comment preservation with automated refactoring.

23:37 coventry: 4clojure and Clojure Programming are still the best resources for complete beginners, right?

23:37 technomancy: arrdem: that's what ;; is for

23:38 arrdem: I think I've seem three codebases that used the ;+ convention...

23:39 most just used ;; or ; in isolation

23:39 technomancy: maybe you'll see it more once we start to see code-rewriting tools

23:40 alandipert: technomancy: https://github.com/adereth/leiningherk/blob/master/lein.gk :-)

23:40 bellkev: xeqi: hmm, I'll have to check it out. If I make something a :dev dependency, can I just include e.g. a cli dependency in a cljs file and it won't complain? I'll have to familiarize myself with profiles a bit more...

23:40 technomancy: alandipert: whaaaaaaaa

23:40 arrdem: alandipert: whatrudoing

23:40 technomancy: oh, bin/lein

23:40 niiiice

23:42 amalloy: technomancy: i bet you feel dumb, now that there's a ;;;; port of lein ;;;; followed by only a hundred LOC

23:46 bellkev: xeqi: actually nvm, it looks like I just need to learn how cljs macros work... Since macros work at compile-time, and the cljs compiler runs on the jvm, cljs macros have to be defined in a clj namespace. So I should be fine...

23:48 talios: right - enough of this lein malarky - lein != supported for now. contractor can suffer

23:53 cljr: hi, i have a question concerning hex codes....in python i can specify ff as "\xff", i found unicode representations as "\u00ff" in java, but it isn't directly equivalent, im not quite sure what im doing wrong as i dont work with hex/binary data, any nudge in the right direction would be helpful and appreciated

23:54 arrdem: ,(.toInt (first "\xff"))

23:54 clojurebot: #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \x>

23:55 arrdem: $google java string hex literal

23:55 lazybot: [hex - \x Escape in Java? - Stack Overflow] http://stackoverflow.com/questions/3613759/

23:55 cljr: arrdem: yeah i actually found "\u00ff" from that, but again it isn't the exact same and i dont know enough to continue

23:57 dcolish: 0xFF

23:58 arrdem: cljr: &&(= 0xff 0xFF)

23:58 lazybot: HOW DO I USE YOU

23:58 TEttinger: ,"\0ff"

23:58 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Invalid digit: f>

23:59 TEttinger: arrdem: ##(= 0xff 0xFF)

23:59 lazybot: ⇒ true

23:59 arrdem: (inc TEttinger)

23:59 lazybot: ⇒ 7

23:59 arrdem: ~botsmack

23:59 clojurebot: clojurebot evades successfully!

23:59 arrdem: (dec clojurebot)

23:59 lazybot: ⇒ 31

Logging service provided by n01se.net