#clojure log - May 28 2013

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

1:18 expt: i have a set of lines, read from a file, where some lines are parents (with an id) and other lines are children (with no ids)

1:18 callen: amalloy: ping

1:18 expt: how would i, on a line-by-line basis update the children to have the id of the parent.

1:19 imperatively, this would be pretty easy, but I am looking for an idiomatic way in clojure to handle this

1:19 callen: amalloy: if I've got a thread-scoped global var wrapped in an atom getting reset by a ring middleware, would that stop functioning properly outside of a thread per request model? (Netty/Aleph vs. Jetty)

1:19 expt: assoc the id to be whatever the id of the parent is?

1:20 expt: oh wait, this is a file?

1:20 expt: yes

1:20 @callen

1:20 callen: expt: can you describe the format at all? are we talking tab delimited?

1:20 expt: how do you know what a child's parent is?

1:20 are they consecutive?

1:21 expt: callen: it is a mvel file, for a drools engine, that I am parsing. the first description line has the rule and an id associated with it

1:21 amalloy: callen: i don't understand the structure, but "thread-scoped...outside thread per request" sounds bad

1:21 brehaut: ,(let [ps (partition-by :id [{:id 1 :t "a"} {:t "b"} {:t "c"} {:id 2 :t "d"} {:id 3 :t "e"}])] (map (fn [parent, children] [parent, children]) ps (rest ps)))

1:21 clojurebot: ([({:t "a", :id 1}) ({:t "b"} {:t "c"})] [({:t "b"} {:t "c"}) ({:t "d", :id 2})] [({:t "d", :id 2}) ({:t "e", :id 3})])

1:21 brehaut: + errors when the first record does not include an id, and no actual stitching included

1:21 expt: and the following lines, belong to the body.

1:22 callen: amalloy: it works fine, I'll keep running naked.

1:24 hiredman: if only there was a sweet reducers partition-by for doing reducers based io with...

1:26 expt: callen: it is essentially like a function block in java, but instead of a function declaration and name, it has a 'rule' statement and an id. the rest of the lines are essentially a scope, opened and closed by braces. since the first line is the rule, I can easly get the id, and pass that value to the subsequent lines.

1:27 callen: hopefully without some type of outside variable i would need to reset on every group, though it would be a solution.

1:28 callen: i have structured each line as a map, with a ordinal, key, id, and string.

1:28 callen: expt: is this some adhoc file format? :\ My approach, based on a limited understanding of the specifics, would be to parse each row into a map representation with a references between the children and parents.

1:28 okay, yes, uhm. That.

1:28 now assoc the ids from the parents into the children.

1:28 direct object references would be more efficient than keys that you have to scan for.

1:29 expt: callen: so you are advocating a tree stucture then for each rule? am i understanding that correctly? or at the very least, a list associated to the parent?

1:30 callen: expt: closer to the latter, don't take anything I say too seriously, I'm working off a limited understanding of the format.

1:30 but yeah, the closer your work is to just assoc/dissoc'ing maps the happier you'll be.

1:31 expt: callen: okay, thanks for the tip on that

1:31 callen: expt: I've only used mvel with a search engine, I've avoided drools at all costs.

1:31 expt: callen: alright, i will take look at it from that perspective.

1:32 callen: @drools... yeah, well, that is why this project came about, as the client wanted to get rid of the engine, but have several thousand rules they need parsed.

1:32 callen: expt: solid. Good luck.

1:33 expt: callen: at any rate, thanks for the alternate perspective

1:33 callen: expt: if I had coffee available to me and a refheap of the format I could be more useful.

1:33 You can help with the latter, the former is up to me.

1:33 but the coffee is seriously critical.

1:33 expt: callen: haha, if you were around, i would buy you the coffee ;)

1:35 callen: thanks, I will see what I can work up that is not confidential, and ping you back perhaps if your previous idea stymies me, but I do appreciate the perspective, it already seems to be a better take than a flat line, re-association approach.

1:35 callen: thanks

1:36 frankenBits: Hi Clojurians

1:36 Any clojurescript guru in the room?

1:38 brehaut: ~anyone

1:38 expt: frankenBits: yes, there are. i don't claim it (guru status), but if you ask the question, someone will respond, generally

1:38 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

1:38 callen: expt: cheers.

1:38 expt: callen: right back at you. thanks.

1:38 frankenBits: thanks expt, i think the question i have is pretty basic..

1:39 running clojurescript for the first time off my machine

1:39 (dotimes [x 10]

1:39 (.write js/document (str

1:39 callen: frankenBits: IRC is a little more asynchronous. and a bit like fishing.

1:39 frankenBits: "<p>Hello, world! For the "

1:39 (+ x 1)

1:39 " time!</p>")))

1:39 callen: frankenBits: use refheap to post code please, don't paste into the channel.

1:39 frankenBits: and when asking question, just you know, toss stuff out there and see who bites.

1:39 questions*. Don't need to ask to ask, ya know?

1:39 frankenBits: gotcha

1:39 callen: either somebody is around or they ain't. :)

1:40 frankenBits: haha rite :) newbie to irc as well

1:40 one sec let me get this posted so it makes more sense

1:40 expt: well, frankenBits, welcome to clojure, AND irc

1:41 frankenBits: thanks Clojure opening new doors ;)

1:42 callen: frankenBits: https://www.refheap.com/

1:46 frankenBits: Here is the writeup

1:46 https://www.refheap.com/15084

1:47 almost seems like a bug in clojurescript

1:48 brehaut: ,((fn [& r] (prn r)) 1 "two" :three)

1:48 clojurebot: (1 "two" :three)\n

1:49 brehaut: you are collecting the variadic arguments as a seq, and then passing that seq to the .write method.

1:50 if .write were a funciton i would say you should be applying it, but i dont know how that translates to clojurescript method stuff

1:50 and javascripts Function.prototype.apply shenanigans

1:52 frankenBits: hmm…i see what you are saying

1:52 so if i do something like (str input)

1:52 would that do the trick?

1:52 brehaut: yeah it will

1:54 so, (.apply (.-log js/console) js/console (array 1 2 3))

1:55 that is an ugly way to get a method and apply it

1:55 i presume there is a smarter way somewhere in the lib

1:55 (it needs an array, not a collection too)

1:56 frankenBits: even wrapping it in (str ) doesn't work

1:56 brehaut: ,(str "a" 1 "two")

1:56 clojurebot: "a1two"

1:56 brehaut: oh, you want (apply str input)

1:56 again, because you want to pass the sequence as variadic arguments, not as a collection

1:57 frankenBits: ahh!

1:57 brehaut: btw, writeBody, and camelCase in general is poor style in a lisp. it should be write-body

1:57 frankenBits: Thanks for the tip

1:58 newish to lisp..did my own emacs lisp hacking but never followed conventions per say..good to know

1:59 callen: frankenBits: per se

1:59 frankenBits: latin for, "in itself"

1:59 brehaut: http://mumble.net/~campbell/scheme/style.txt is a good style guide

1:59 callen: or "through itself"

2:00 frankenBits: it's a way of isolating a subject or disconnecting it with the typically attendant qualifiers.

2:00 "I was a banker per se, but not a wall street fat cat."

2:00 frankenBits: brehaut u rock! it worked

2:01 called, thnx, it's late here in the states..late night grammar isn't great

2:01 callen*

2:01 my late night grammar isn't great*

2:03 callen: frankenBits: it's late here too (LA)

2:03 dsantiago: I'm in LA now btw.

2:03 amalloy: I draw near! Bwahahahaha

2:04 frankenBits: How are you awake…I'm in Chicago and its 1am here

2:04 amalloy: i know. Raynes was so excited to have you in his apartment i had to avert my eyes

2:05 stirfoo: I wonder how much scheme r. hickey has written. He adopted ? for predicates instead of -p.

2:05 callen: This is Raynes on callen's laptop. Weee

2:10 frankenBits: it's 2302 atm. I'm currently deciding if I want to try to do anything else tonight or not :P

2:10 frankenBits: I'm usually up late. Like 2 or 3.

2:10 amalloy: I walked down the pier. Really cool *_*

2:10 amalloy: 2302?! i overslept by two centuries!

2:11 three, i guess

2:11 whatever, math

2:11 callen: amalloy: ahoy rip van winkle

2:15 frankenBits: callen: nice i stay up late sometimes..can't do it as often anymore not thattt young anymore haha

2:15 sirfoo can you elaborate? on -p?

2:16 stirfoo: frankenBits: common lisp's way to denote a predicate

2:18 frankenBits: stirfoo: interesting i've been reading on lisp by paul graham, common lisp looks interesting..a little cumbersome compared to clojure syntax at least that's

2:18 how it feels going from Clojure to CL

2:19 is the predicate system more robust in CL?

2:20 stirfoo: on lisp is a great book, but a lot of it would be difficult to transpose to clojure becuase of the immutability inherant in the language. (I've tried a few things). You really have to change the way you think with clojure.

2:20 frankenBits: it's just a '?' suffix vs a '-p' suffix, nothing more

2:23 frankenBits: i definitely agree, it's a mixed bag because of CL mutability. I read good things about on lisp's approach to teaching macro's

2:23 haven't gotten to that point yet

2:23 primarily reading it for that

2:24 Who says LISP has bad marketing? I bit Paul Graham's marketing pitch on lisp

2:24 stirfoo: frankenBits: come to think of it, I learned more about cl macros from that book than anywhere else =)

2:26 frankenBits: :D awesome, that's the killer feature i need to really learn. I've read the Clojure macro tutorials felt a little lacking

2:27 stirfoo: I have cl the language, 2nd edition around here some where. I wore the pages out on that one but it's been a couple of years since I wrote any cl. clojure is just too much fun.

2:29 frankenBits: stirfoo: did you have a day job doing CL?

2:29 stirfoo: frankenBits: no, I'm a stricly-for-fun programmer

2:30 writing code is like trying to solve a puzzle with a gazillion solutions =)

2:31 frankenBits: stirfoo: agreed coding is too much fun, i learned so much about a variety of fields just by studying programming out my own interest

2:31 sometimes it feels like I'm debugging in real life like i would in a program

3:09 lynaghk: I need a queue (with multiple consumers) containing the topologically ordered vertexes of a (changing) graph

3:09 any suggestions on how to implement? I have the topological sorting already worked out, but I'm not sure the best way to setup a queue

3:10 tomjack: you mean it's like a mutable priority queue where priority is determined topologically, and you enqueue a node every time it changes?

3:10 lynaghk: I considered throwing a java.util.concurrent queue behind an atom, but that just seems gnarly.

3:11 tomjack: not every time it changes. Say I have two worker threads pulling things off the queue and a third thread that sometimes adds new nodes/edges to the graph (and thus needs to add things and sort the entire queue)

3:12 tomjack: 'things' == nodes?

3:12 vertexes

3:12 lynaghk: tomjack: yeah

3:12 tomjack: how do the edges fit in

3:12 oh

3:13 lynaghk: to determine the sorting order

3:13 tomjack: right

3:13 lynaghk: I did look at the java.util.concurrent priority queue (which accepts a comparator), but I don't think that will work because the docs didn't mention that it would resort entirely on each add to the queue.

3:14 tomjack: can you add a node already in the graph to the queue?

3:15 or 'each add' is a new node being added to both graph and queue?

3:15 lynaghk: I can add an existing node to the back of the queue

3:15 the use case is a build process where during the build a target may specify additional dependencies

3:16 in which case the current build is killed (since the new deps haven't been built yet), the deps are added to graph, and the work queue needs to atomically become the topological sort of the graph.

3:17 the new graph, that is.

3:18 tomjack: do you really need j.u.c or a mutable queue?

3:18 lynaghk: tomjack: I'm open to other options. I need something that can be consumed by multiple threads

3:20 tomjack: if the current build is killed, why do you care about an existing queue?

3:20 I mean, you kill the current build but then you want to only redo what didn't already get done last time?

3:21 if you start over from scratch I don't see why you'd need a mutable queue that atomically changes sort order - just restart the whole process from the new graph

3:21 lynaghk: the queue has, say, [A B C]. In building A we discover that it depends on D E, so we kill the build for A and the queue should now be [B C D E A]

3:23 tomjack: I see, just kill the target whose deps changed?

3:23 lynaghk: tomjack: yeah

3:25 tomjack: interesting problem :)

3:25 a priority-like queue is not quite right, right?

3:26 I mean say [A B C] and B depends on A

3:26 if some worker pops off A and the queue is [B C], B cannot be popped

3:26 until A is done. yes?

3:26 lynaghk: tomjack: I'm not sure about the formal definition of a priority queue, but the implementation in java.util.concurrent won't work because the comparator can change.

3:27 tomjack: assume for simplicity the topology is fixed

3:27 lynaghk: tomjack: yes, but if that were the case then the sort would have been [C A B]

3:28 yunfan: anyone could give me an example of using sqlkorma doing (-> create-db build-tables insert-records selecting-stuff ... )

3:28 tomjack: then C is popped, A, and now the queue is [B], how does a worker know that they need to wait for A to do B?

3:29 yunfan: am i in the blacklist?

3:29 tomjack: a queue doesn't care about completion

3:29 lynaghk: tomjack: good point. I haven't considered that case yet.

3:30 tomjack: I will need to add per-target locking in any case, so here the worker will look at the graph, see that B depends on A and that someone is already working on A, so he'll go to the next item.

3:31 tomjack: ouch

3:31 lynaghk: er, it. I need to stop anthromorphising threads

3:34 mthvedt: does discovery of dependencies have to be lazy?

3:34 it looks pretty easy if you get the whole tree at once

3:36 lynaghk: mthvedt: yep, that's what makes it fun =P

3:36 a lot of things would be easier if we knew everything at once.

3:38 mthvedt: lyanghk: how about doing it recursively with workers pausing and adding child tasks, then waiting for them before they continue

3:38 you could have some mechanism to make sure the # of 'active' workers is constant, and work doesn't overlap

3:39 lynaghk: mthvedt: that was my first approach, but the number of threads you need to prevent deadlock is unbounded.

3:40 mthvedt: lyanghk: i'm missing how it can deadlock so long as it's partially ordered

3:42 lynaghk: mthvedt: it could deadlock if you limit the number of threads. E.g., You have A -> B -> C -> D -> ...

3:42 where "->" means "depends on".

3:43 so you will lock if your graph has a depth greater than the number of threads you have

3:44 mthvedt: lyanghk: well if you have deps A B and C, you can spawn threads for B and C and recurse on A

3:46 lynaghk: I may just have to finally write myself a dosync. In any event, I should sleep on it first. Thanks tomjack and mthvedt.

3:53 callen: tomjack: now I want to play beer pong o_O

3:53 amalloy: lynaghk: is this really going to be handling workflows so deep that you can't afford a thread for each depth? i mean, a more elegant solution would be fun, but for most reasonable inputs it sounds like a thread would work, and that would be easier

3:53 tomjack: beer pong is bad

3:53 callen: tomjack: I recall winning the last time I played, and that's all that really matters.

3:54 I like #winning. #tigerblood #warlock

3:54 tomjack: alcohol is a terrible sacrament imo

3:54 callen: tomjack: sacrament? It's beer pong not passover ;)

3:54 tomjack: I enjoy thinking about most social groups as cults and behaviors as rituals

3:55 callen: tomjack: fraternities must be horrific for you.

3:56 tomjack: yes, but also disappointingly boring

3:56 the religion at some college parties is awesome though

3:56 callen: tomjack: Bacchus?

3:58 tomjack: I dunno what it is, but it's weird :)

4:02 mthvedt: is it not written that on the night when he was betrayed, our lord produced ping pong balls and threw them into red solo cups, saying this is the sacrement of beer pong given unto you

4:04 callen: mthvedt: I have a new idea for startup poker nights now.

4:24 ddellacosta: how do you reload a namespace from a file (say if you've edited the file) in a cljs repl? I'm using piggieback.

4:27 never mind, I guess load-file does it.

4:31 hmm, except it seems to add extra instances of the same functions…

4:47 noncom: what is better for fast mutable state: a map of 5 atoms or an atom of a map with 5 kvs?

4:48 in 1st case i do individual derefs and swaps, in the second case i swap the whole map after assoc

4:48 moonchrome: noncom, I think that has more to do with how you want to access them then performance

4:49 noncom: moonchrome: putting an interface function on it hides details anyway so i thought maybe there is some existing bias in the community

4:50 mthvedt: noncom: depends on access patterns, but consider that the cost of concurrency is orders of magnitude higher than chasing a few extra refs

4:50 noncom: well i guess i'll just have to (time) and measure my usecase

4:51 with both types of access

4:51 moonchrome: noncom, atoms are just CAS operations and pointers - not much overhead there - it really depends on if the data is coupled / needs to be updated simultaniously or is it separate

4:52 mthvedt: moonchrome: CAS is not fast when contended. it's faster than synchronization, but that's not saying much :P

4:53 moonchrome: mthvedt, well technically CAS is a atomic operation :P

4:53 it's just the retries that screw you :P

4:54 mthvedt: moonchrome: yup, but if you have to ask about concurrent performance, it's probably because the retries are screwing you :P

4:55 moonchrome: I feel like noncom is doing premature optimization otherwise he would have posted some test case and profiling info for his problem

4:56 noncom: yeah, i think it is more of premature optimisation actually

4:56 mthvedt: well, it was an optimization question. the answer is either don't optimize or optimize for the typical case

5:00 callen: noncom: atom of a single map with 5 kvs. See how it shakes out.

5:17 noncom: i think that yes, for my case, and considering the required concurrency model, i go with one atom map

5:19 tomjack: cool, sorta kinda looks like I got alt(s)! in go working https://www.refheap.com/3188f10dde7b99b924c2bd299

6:00 augustl: does infoq have a way to list all presentations for a specific conference? Clojure/west presentations seems to have started popping up

6:01 katratxo: augustl: http://www.infoq.com/clojure-west-2013/ ?

6:01 augustl: katratxo: woo! How did you find that link? :P

6:02 tried clicking on everything that said "Clojure/west" on a presentation I found, no dice..

6:03 katratxo: augustl: below the video you have some "tags"

6:03 augustl: katratxo: ah, thanks

6:04 katratxo: augustl: np

6:37 asaleh: I am trying to do rpc in clojure and I am wandering ... I have a function (defn call [url username password command args] ...), but most of the time the url, username and password stay the same ... is there a way how would I elegantly implement this?

6:39 I am thinking about something like (with-rpc url username password (call :command1 []) (call :command2 []))

6:42 augustl: asaleh: I'd prefer to create some sort of "context" you could pass in

6:42 but as long as with-rpc is a macro that allows you to call "call" by passing in arguments I'd be happy :)

6:43 ucb: asaleh: I'd use partial

6:43 augustl: partial would only solve it for one function call though?

6:43 ucb: asaleh: e.g. (def rpc-call (partial call some-url user passwd))

6:43 augustl: well, then you could just call (rpc-call command args)

6:44 augustl: ah, good point.

6:44 ucb: unless I'm missing something

6:44 augustl: (let [rpc (partial do-rpc "username" "password" "url")] (rpc "foo") (rpc "bar"))

6:44 ucb: yup

6:45 asaleh: augustl, ucb well, that looks great, thanks! :)

6:56 tomjack: cljs port seems to be working :) https://www.refheap.com/2d26edb26ee3b299a92a02a32

6:58 with poor man's binding conveyance

7:04 dbushenko: hi all!

7:12 tomjack: bbloom: dnolen: https://github.com/tomjack/core.async/commits/cljs-port

7:26 clgv: what is the current library to use for JNA?

7:26 or JNI

7:26 I mean clojure library

7:30 augustl: clgv: I suppose interop would work well for this.

7:30 clgv: augustl: well a minimal language for the native call would be preferable.

7:31 I found https://github.com/bagucode/clj-native and https://github.com/Chouser/clojure-jna/network

7:33 edtsech: hey guys, what is the best solution for partial content support? I've found https://github.com/remvee/ring-partial-content but it's pretty old.

7:36 jtoy: hi

8:00 does anyone see what I'm doing wrong here? I'm trying to get back a list of single items but i get back a list of lists with 1 item each: (map (fn[xs] (last (sort-by #(-> % :at) xs))) (group-by #(-> % :user :id) candidates))

8:11 I found it

8:12 this is pretty ugly code: (map (fn[xs] (last (last (sort-by #(last (last (-> % :at))) xs)))) (group-by #(-> % :user :id) candidates))

8:13 hyPiRion: jtoy: what. Can you give me a small example of what candidates is, and what you want as output?

8:19 clgv: ok clj-native works. but where do I have to put the library so that it can be loaded?

8:22 jtoy: hyPiRion: my example is not working, but im trying to do something like this: https://www.refheap.com/15098

8:25 hyPiRion: jtoy: could you explain it in English? (i.e. "I want a list of users sorted on the length of the user name, ascending")

8:27 jtoy: hyPiRion: for each b group, I only want the one with the longest a, so i have a unique list of b's with the one with the longest a

8:27 isee what i did wrong

9:23 is there a method where i can do something and then return itself?

9:24 ohpauleez: jtoy: You want to do something to a thing, and then return that thing?

9:24 mefesto: (doto obj (thing))

9:24 ohpauleez: or a function that does some work and returns the function itself

9:25 the former is `doto`

9:25 the latter seems like a destructive function

9:25 which may be ok, but yes, you can do that too

9:26 (fn f [] (inc 1) f)

9:26 mefesto: ohpauleez: did you give a talk at the last conj?

9:26 jtoy: ah doto, cool

9:26 i just want to println it

9:26 hyPiRion: btw, i just got it working correclty i believe: (map (fn[xs] (last (sort-by #(-> % :at) xs))) (map last (group-by #(-> % :user :id) candidates)))

9:26 ohpauleez: mefesto: I did - on CLJS and general design

9:26 mefesto: ohpauleez: i recently saw a video of that. really great stuff!

9:27 ohpauleez: jtoy: (doto thing (prn))

9:27 mefesto: Thanks! I'm glad you enjoyed it!

9:27 mefesto: ohpauleez: got another talk coming for the next conj?

9:28 ohpauleez: I have not submitted anything - I gave a talk at ClojureWest and I've been continuing that work a bit

9:28 I've also been working on a lot of "enterprise Clojure" and would love to share about those experiences - the general stack

9:29 But I might take a break (I'll be moving across the country right around the same time)

9:29 jcrossley3: ohpauleez: i'd like to hear that talk :)

9:29 mefesto: where abouts you moving?

9:29 ohpauleez: jcrossley3: I'm sure you would :)

9:29 mefesto: west -> east coast?

9:30 ohpauleez: From Portland, OR back to Boston area

9:30 yeah

9:30 I've switched coasts every year for the past three

9:30 so I'm settling in back east

9:30 mefesto: wow

9:31 yeah that sounds like a crazy pace of moving.

9:31 anyhow, just wanted to give you some props on that talk. :)

9:33 for anyone interested: http://www.youtube.com/watch?v=1zdzivUmL4s

10:25 TimMc: ohpauleez: Ah, where in teh Boston area?

10:25 ohpauleez: TimMc: Hey man! Unsure yet

10:30 danlarkin: ohpauleez: you bastard

10:31 ohpauleez: danlarkin: haha - not until October

10:31 I'm a heartbreaker

10:31 danlarkin: you tease me and then you leave me

10:37 bbloom: ohpauleez: make up your mind dammit

10:38 ohpauleez: bbloom: I loathe moving more than anything

10:38 but I end up doing it all the time

10:38 bbloom: ohpauleez: as somebody else who did the bicoastal 6 month flip flop for 4 years a while back… yes fuck moving

10:38 ohpauleez: I think this time, for real, I'll stay put for a bit

10:39 bbloom: in boston? booooo ;-)

10:48 rbxbx: ohpauleez: pre-emptive welcome back east :D

10:48 ohpauleez: couldn't hack the portland winter either? :p

10:49 llasram: I do wish we'd go ahead and finish linking BAMA all together

10:50 Would make the East more attractive/terrifying

10:52 gfredericks: $google BAMA

10:52 lazybot: [Bama Boatanchor Manuals Archive] http://bama.edebris.com/

10:53 llasram: gfredericks: http://en.wikipedia.org/wiki/The_Sprawl

10:55 jcrossley3: gfredericks: thanks to you, TIL what "heuristic outcomes" are :)

10:55 gfredericks: jcrossley3: it feels like a euphemism

10:55 don't worry boss, it was just a heuristic outcome. we'll have it cleaned up momentarily.

10:55 jcrossley3: :)

10:59 ohpauleez: rbxbx: I think Portland is a gorgeous city - I really enjoy it here. I'm definitely an east coast kid at heart, as is the Mrs. New England is better for both of us professionally as well

10:59 gfredericks: jcrossley3: I read the 3PC article for a while but there still seemed to be obvious failure scenarios they weren't accounting for

10:59 maybe it's just wikipedia not being an ideal tutorial

10:59 ohpauleez: rbxbx: but yes the "winter" here is the serious price you pay for the summer

11:00 gfredericks: what are portland winters like?

11:00 bbloom: extrapolating from seattle: gray.

11:01 ohpauleez: It rains almost non-stop, usually not hard, but at least always a constant mist

11:01 jcrossley3: gfredericks: very possible. fwiw, mark is darn responsive for a CTO of a billion dollar company (he's an academic at heart), so feel free to ping him for links/references.

11:01 ohpauleez: it rarely drops below 33F degrees, but because it's so damp, it hurts your bones

11:01 gfredericks: yeah that doesn't sound like it deserves the term "winter"; maybe "seattle" would be a good name :)

11:02 jcrossley3: will do -- thanks

11:02 ohpauleez: but there is no place in the US with a more beautiful summer than PNW

11:03 bbloom: ohpauleez: oh yeah. but don't tell anyone that. you're going to drive up the price of my future summer home

11:03 hyPiRion: Oh, you want to discuss summers?

11:03 ohpauleez: bbloom: HA!

11:03 hyPiRion: The Norwegian summer was beautiful this year.

11:04 emphasis on "was" =/

11:04 rbxbx: ohpauleez: I agree pretty much 100%.

11:04 ohpauleez: I found myself a bit too caustic for the west coast :p

11:04 gfredericks: hyPiRion: summer ends in late may?

11:06 obligatory oatmeal reference? http://theoatmeal.com/pl/minor_differences5/suit

11:07 arkx: Anyone else seen issues with :output-wrapper true & :optimizations :whitespace?

11:07 hyPiRion: gfredericks: we had like 3 days with 80 F up here, then a flood and tons of water came and destroyed it all

11:07 now it's like 45 F

11:08 gfredericks: it was 45 here a few days ago and now 80

11:08 nDuff: gfredericks: ...that's one of the points on which I'm a bit disconcerted about moving to the East Coast. If wearing a kilt to work doesn't fit in so well... meh.

11:08 ucb: nDuff: proper tartan and all?

11:09 rbxbx: gfredericks: nice.

11:09 nDuff: ucb: Family tartan's pretty ugly, so I usually go the Utilikilt route.

11:09 ucb: heh

11:09 llasram: Two of the guys at my company briefly tried to get "pantsless friday" going, but AFAIK only they ever showed up be-kilted

11:09 hyPiRion: I think I would fit perfectly into the American workplace. I have the right circadian rythm for american timezones at least.

11:10 * nDuff is trying to decide what to do name-wise on getting married later this year -- SO is an actor and needs to keep her name for marketing purposes; we might just both adopt her ex-wife's name (McArthur).

11:10 rbxbx: hyPiRion: your body will readjust to fucked up times again.

11:10 gfredericks: "nDuff McArtur"

11:10 rbxbx: or so that has been my experience

11:10 hyPiRion: rbxbx: yeah, I'd guess so

11:11 Okasu: https://gs1.wac.edgecastcdn.net/8019B6/data.tumblr.com/f93397ba62d722abb4319f4adcea46d1/tumblr_mmkwc5QYE31qzsjkco1_500.png Regardless strange weather and all that kind of stuff. We're pretty much doomed.

11:15 TimMc: Okasu: It's pretty clear that saying "we must not go above X ppm" is not an effective approach; we've crossed a few such thresholds already.

11:18 hyPiRion: Okasu: http://i.imgur.com/HN1fMxT.jpg

11:19 samrat: is there any way I can setup nrepl to (use 'clojure,repl) when I do (in-ns ..)?

11:19 automatically, I mean

11:20 gfredericks: samrat: I'm 99% sure there is, and I have no idea what it is.

11:21 middleware at worst?

11:22 am I wrong for wanting to replace compojure with something more data-oriented?

11:23 weavejester: gfredericks: Nope. Compojure has it's strengths, but transparency isn't one of them.

11:24 gfredericks: weavejester: has this been tried before?

11:24 weavejester: gfredericks: Pedestal has data-driven routing, but it's locked up with a bunch of other things.

11:25 gfredericks: hrm

11:27 what if routing was separated into two phases -- identification and handling -- such that you could add your "routing middleware" early in the pipeline and it would just add some data to the req about which route matched and the params inside it; then you could even have your underlying handler be a multimethod that dispatches on the data in the req

11:28 I've been wanting to add data to my logging about which route is being handled, but none of my middlewares have access to that information :/

11:28 ucb: gfredericks: I like that idea

11:29 (fwiw)

11:30 gfredericks: would also let you do things like associate arbitrary metadata with individual routes that later middlewares could look for

11:31 e.g., "these routes require a JSON content type", then a later middleware that returns a 400 when appropriate

11:31 ucb: gfredericks: what if 1+ routes could handle the request? Or at least initially matched the URL? would you have each handler either produce a response or remove the tag?

11:31 (perhaps I'm missing the point completely here)

11:32 gfredericks: the matching could still be ordered like it is in compojure

11:32 so I'm not sure where that ambiguity would come from

11:33 ucb: gfredericks: /user/:id and you have both XML and JSON endpoints?

11:35 gfredericks: such that request look like /user/123.xml and /user/123.json, or distinguished by the headers?

11:37 ucb: gfredericks: yeah, I was sort of hinting at matching on headers as well. Your handler, based on URL only (assuming no .xml or .json ending) would then be ambiguous otherwise.

11:38 gfredericks: hmmm...now I'm wondering if the "matching" middleware could be totally generic, and just add path data to the req, and all the work could be done in a multimethod

11:39 probably would want more semantics than that

11:40 ucb: but in any case if it's a multimethod it can be based on anything in the req at all

11:40 or the traditional predicate dispatch-like approach if multimethods are too rigid

11:41 ucb: gfredericks: yes. I like the general idea. I was just seeing if I could poke you to tease out more details and then go write it myself ;)

11:41 gfredericks: oh you can definitely write it yourself I don't have time for this nonsense

11:41 ucb: heh

11:41 me neither sadly

11:41 well, actually, you never know

11:44 alandipert: dnolen: does advanced mode rely on :static-fns true?

11:45 gfredericks: ucb: I'm imagining a first pass could be something similar to defroutes that instead returns two functions -- the middleware and the base handler

11:46 ucb: gfredericks: I may have some free time on Thu/Fri

11:46 dnolen: alandipert: it does

11:46 alandipert: it defaults to true in advanced mode

11:48 alandipert: dnolen: ok cool

11:48 dnolen: we have found a bug with static-fns that causes gclosure to compile indefinitely, will collect more info and report back

11:49 dnolen: s/bug with/bug related to

11:50 dnolen: alandipert: strange, look forward to details

11:50 ucb: gfredericks: hum, if there was something like defroutes that returned the handler and the middleware (perfectly reasonable for a first pass) then it'd have to take the bodies of all handlers. Correct?

11:51 dnolen: xkcd HN problem in core.logic http://news.ycombinator.com/item?id=5780663

11:51 gfredericks: ucb: yeah, like it curretnly does

11:51 ucb: gfredericks: sure, I was pondering on the size of that beast once it gets fairly complex. I suppose you could have as body a function and nothing else.

11:52 gfredericks: body for the route handler that is

11:53 gfredericks: size shouldn't be any worse than current defroutes, right?

11:53 ucb: sure, as I said, I was just pondering whether this approach would allow for extra niceties

11:57 gfredericks: hmmmmm

11:57 maybe better to start with designing a data-description of a route?

11:58 which is probably tricky but worth doing if it can be done

11:58 ucb: *nod*

11:59 gfredericks: should be easy for the most common kinds of routes. Once you allow regexes though...

12:02 ucb: hum, can you do without regexes?

12:02 gfredericks: I've never used them :)

12:02 I don't do much webby stuff though; usually just rest/json stuff

12:02 ucb: exactly

12:02 well, me too, so that's why I'm wondering when/where you'd use regexes

12:03 gfredericks: probably as a restriction on any of the path components

12:04 regexes can be data. either as a raw string or a proper regex. not sure which is better.

12:05 ucb: hum

12:06 gfredericks: ,(str #"\d{4}")

12:06 clojurebot: "\\d{4}"

12:06 ucb: perhaps as regexes with #"" since they're compiled already?

12:07 gfredericks: would be fun to be able to serve this stuff as edn

12:09 ucb: heh

12:10 ohpauleez: dnolen: Your core.logic sword is mighty and sharp

12:10 that's awesome stuff

12:10 supersym: ohpauleez: agreed! I was playing around with it yesterday as well :)

13:28 bmentges: I wish it had a clojure/functional programming pill, you take it and learn it all.

13:29 supersym: using Refs, how would I delete a key? feed it nil or?

13:31 hyPiRion: ,(let [foo (ref {:key 15})] (prn foo) (dosync (alter foo dissoc :key)) (prn foo)) ;?

13:31 clojurebot: #<Ref@de9e85: {:key 15}>\n#<Ref@de9e85: {}>\n

13:31 supersym: dissoc.. thanks :)

13:31 hyPiRion: :D

13:32 supersym: thats easy to remember :P

13:41 klrr: does "ns" define a module?

13:42 tomjack: "edn"/"readin'" - coincidence?

13:45 bbloom: klrr: it defines a _N_ame__S_pace, which you might call a module depending on how technical you want to be about what a module is

13:47 klrr: bbloom: okey, im not wanna be techical since im not really learning clojure :P thanks though! :)

13:56 supersym: hyPiRion: dissoc-in is removed?

13:57 TimMc: klrr: I suppose that depends on what "module" means to you.

13:59 tomjack: (instance? clojure.lang.IMapEntry form) (outer (vec (map inner form)))

13:59 :(

14:01 supersym: oh nm...found it

14:02 hyPiRion: supersym: it is?

14:02 ,(dissoc-in {:a {:b 1}} [:a :b])

14:02 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: dissoc-in in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:02 sevvie: hi everyone. I've been working through _Clojure Programming_, slowly, and ran into an issue with some code from the book; I can't tell if it's something I messed up or not?

14:02 https://gist.github.com/sevvie/5664676

14:03 hyPiRion: well, update-in with dissoc is probably the correct approach then

14:03 sevvie: It's "Wilson's Maze" from the book, but it doesn't actually draw the maze. It creates the window, draws the border for the maze, but... is otherwise empty.

14:03 Foxboron: sevvie: you can fix those ends paranthesis D:

14:03 end*

14:04 sevvie: Foxboron, I know I know XD It just helps me see things. I'll take the training wheels off for myself eventually.

14:11 tieTYT2: what I find weird about clojure is that if I def something, it can be accessed from anywhere (unless it's private). If that def is a java object with setters, is this similar to a global object?

14:12 sevvie: Foxboron, I updated the gist with tucked-in parens.

14:13 bbloom: tieTYT2: that's not similar. that IS a global object :-P

14:13 tieTYT2: bbloom: ok, and IME that's bad

14:14 now if I def an atom instead, why isn't that bad?

14:14 bbloom: tieTYT2: that's bad too. it's just convenient as hell during development

14:14 in general: avoid doing that

14:14 tieTYT2: how do you avoid it? Pass it around?

14:14 nDuff: ...well, not _strictly_ avoid. If you're creating dynamic vars, for instance, their non-root contents are thread-locally scoped.

14:14 bbloom: write pure functions & move the mutable state outside

14:14 supersym: hyPiRion: I need to learn myself to watch the namespace, assoc-in, dissoc etc are in other libraries

14:15 tieTYT2: in my limited experience, it seems so much easier in haskell to do that

14:15 supersym: dissoc-in is in contrib... also is it me or do nested hash-maps bring pain

14:15 hyPiRion: what

14:15 tieTYT2: because you have to. In clojure it's not obvious to me how to accomplish that

14:15 supersym: I never seem to get them right

14:16 hyPiRion: ,(assoc-in {:a {}} [:a :b] :c)

14:16 clojurebot: {:a {:b :c}}

14:16 hyPiRion: oh right, dissoc-in is not evident/simple, so it was left out

14:16 tieTYT2: now if your def is just a value (vs a variable) is there anything wrong with that?

14:16 supersym: ah ok

14:18 tieTYT2: To me that feels like a public static final variable in java

14:19 and those don't usually get me in trouble, but it's not idiomatic to use them as much as I do in clojure, so maybe I just don't have the experience to see the problem with that

14:19 bbloom: tieTYT2: swap! basically lets you just transform a pure function into a state changing one, so just write pure functions & then throw a few bang! functions around the top level & you're good

14:19 having immutable global is no big deal really

14:19 constants are good for you :-)

14:22 tieTYT2: ok then, what about def that's dynamic so that one top level function sets a binding?

14:23 for testing purposes, that seems perfectly fine. You can define the binding at whatever scope you want

14:23 bbloom: tieTYT2: stuartsierra has a great talk on this stuff from clojure/west, i dunno if/when it will be available

14:24 tieTYT2: the downside of the dynamic var is that you can only have one of them at a time. you're better off having a map as the first argument to your fns with everything the fn might need

14:24 i use `-> to thread whole systems though pure functions with update-in, assoc-in, etc doing all the real work

14:26 hyPiRion: bbloom: https://mobile.twitter.com/ClojureWest/status/339380818684289026 <- so there will be a release schedule upcoming as far as I understand

14:29 sevvie: I figured out my mistake. My mistake was pure idiocy.

14:30 noprompt: bbloom: i've been finding a lot of joy in doing the same thing recently

14:37 zerokarmaleft: tieTYT2: I think bbloom is referring to http://www.infoq.com/presentations/Thinking-in-Data around the 28:30 mark

14:37 bbloom: zerokarmaleft: also a good talk, but not the 1 i was talking about

14:38 tbaldridge: zerokarmaleft: yeah, the Clojure/West talk centered more about avoid the use of dynamic vars, and how to deal with global state correctly. It was a good talk.

14:39 zerokarmaleft: ah, looking forward to the clojure/west vids getting released then :D

14:39 tieTYT2: bbloom: what do you mean I can only have one of them at a time?

14:40 tbaldridge: tieTYT2: if I have a global var called DB, now my app is locked into only talking to one DB at a time

14:40 tieTYT2: zerokarmaleft: thanks man

14:40 yeah but if you have a global var called dbs, now you don't have that restriction

14:41 you can have a dynamic var that IS a map

14:41 tbaldridge: So how does a function know what DB to use from the global var?

14:41 tieTYT2: how does it with your solution?

14:45 klrr: is a map similar to haskell's list of pairs( "[(a,b)]") datastructure?

14:46 tieTYT2: doesn't haskell have a map type?

14:50 justin_smith: tieTYT2: the difference is the typing I think? I mean what would haskell even do with an object that returned or took arbitrary types at runtime (I am sure there is actually an interesting answer to that question that I am ignorant of)

14:51 tieTYT2: the question is very vague. Conceptually it's the same as haskell's map type I'd think

14:52 there's more ways to look at it than "conceptually" though

14:52 but it's not the same as [(a,b)]. I think that type would allow duplicate keys

14:54 bbloom: tieTYT2: http://www.haskell.org/ghc/docs/6.12.1/html/libraries/containers-

14:54 justin_smith: looking at the definition of Data.HashMap, it looks like hashmaps in haskell are strongly typed on both key and value (taking arguments that determine the key type and value type). I could be misreading though, and this is all off topic for this channel.

14:55 s/definition of/docs for/

14:55 tieTYT2: justin_smith: that is correct, but I didn't consider that a conceptual difference

14:58 bbloom: conceptually, it's probably better to think of a map as a function than as a sequence of pairs

14:59 TEttinger: amalloy: you maintain a fork of lazybot right? do you know how to get the bot to reconnect later if it gets disconnected?

14:59 amalloy: TEttinger: i maintain the real lazybot :P

14:59 TEttinger: oh good

14:59 amalloy: and no, i don't know; ask Raynes :P

14:59 goodness, what kind of mood am i in? :P twice in a row?

15:00 TEttinger: heh I thought Raynes wrote it

15:00 amalloy: he wrote more of it than i did

15:00 Raynes: TEttinger: Raynes did write it, and amalloy helped later on, so amalloy and Raynes keep it in flatland so both of them can work on it.

15:01 TEttinger: cool

15:01 Clojure seems to have a really supportive community

15:01 Raynes: TEttinger: And unfortunately there isn't a reliable way to get the bot to reconnect. It needs to be implemented at the level of irclj, which is partially through a rewrite (and has been for a long time), but will likely go through another because I'd like to try rewriting it with lamina.

15:02 TEttinger: could it keep track of pings without pongs?

15:02 on mine, I tend to get nothing but pings at odd intervals and it doesn't ever get a pong

15:02 Raynes: There are a couple of ways it could work.

15:03 TEttinger: then I restart the bot and it's fine for days

15:03 maybe weeks

15:09 klrr: '(good night)

15:14 lynaghk: amalloy: re: your question from 12 hours ago; yes, it's conceivable that the build dependency stack will be so deep that spinning up a thread for each layer will be trouble.

15:15 amalloy: that was my first approach, though---futures blocking on futures blocking on futures

15:15 amalloy: okay. just wanted to make sure you weren't skipping the easy solution out of some sense of aesthetics

15:15 lynaghk: amalloy: I'm not going to lie, it's definitely also aesthetics. This is a personal bikeshed, so I've got the luxury/curse of demanding aesthetic perfection

15:16 = )

15:21 noprompt: +1 aesthetics

15:41 brainproxy: dnolen: like the recent revs to mori :) how do you feel about exposing some of the ..? functions, i.e. so plain vanilla js functions can say detect whether an argument is a vector or an array

15:42 e.g. `if (mori.is_vector(x)) { ... } else { /* it's an array */ ... }`

15:44 iow, to facilitate polymorphism in js functions that may be called with mori values -or- plain js values

15:48 bobbrahms1: using clojure-maven-plugin clojure:nrepl, how can I set up the classpath so that I can use the classes in my (huge, java) project?

15:49 I fire it up and can't import anything

15:50 I realize this is a total noob question by the way, and I apologize in advance.

15:51 mefesto: bobbrahms1: is this one large project with both clojure and java sources or is the java project separate?

15:51 bobbrahms1: one big project

15:52 but I dont' seem to be able to import anything:

15:52 user> (import 'java.net URLClassLoader)

15:52 ClassNotFoundException java.net java.net.URLClassLoader$1.run (URLClassLoader.java:366)

15:52 mefesto: oh that's odd

15:52 sorry, i got nothing :)

15:52 bobbrahms1: bummer...

15:53 thanks anyhow…

15:53 anyone else?

15:53 dnolen: brainproxy: patch for that welcome

15:53 brainproxy: dnolen: okay will do

15:53 dnolen: brainproxy: I think we should provide all the standard collection predicates, is_vector, is_map, is_set etc.

15:54 brainproxy: dnolen: yeah, I think it will be pretty useful

15:54 I know I have a use for it

15:54 mefesto: anyone use enlive that wants reloadable templates?

15:54 noprompt: bobbrahms1: i think you mean (import 'java.net.URLClassLoader)

15:54 or (import '[java.net URLClassLoader])

15:54 brainproxy: dnolen: don't have time right at this moment, but it's going on the todo list, you'll see a pull req soon

15:54 dnolen: brainproxy: great thanks

15:54 bobbrahms1: thanks noprompt!

15:55 noprompt: np

15:55 mefesto: ahhh didn't see that in the import form

16:05 noprompt: if anyone wants to send PRs or help with Garden i'd sure appreciate it.

16:06 i've been very busy lately and contributions/suggestions would be welcome. :)

16:07 tomjack: even with no binding conveyance and a funky dynamic *done* callback, async clojurescript.test seems much more appealing than e.g. the promise fork of mocha

16:07 noprompt: Raynes: the fs utilities have been mega helpful the past week. <3

16:08 Raynes: noprompt: Happy to hear. Appreciate the <3, but I of course have to give most of the credit to the original author from whom I took over maintainership. And I give credit because there are lots of completely broken shit in fs that I haven't fixed yet that I don't want to be blamed for. :D

16:09 noprompt: Raynes: ohrly? which parts?

16:09 (to be honest i've probably only used a handful of the fn's)

16:10 dnolen: tomjack: are you writing an async version of cljs.test ?

16:10 mefesto: if you ever get tired of coding those skills will translate into politics nicely :)

16:15 bbloom: dnolen: rhickey said that tim baldridge was gonna do one, but i think tomjack took a stab at it for grins

16:19 noprompt: lynaghk: do you still work with angularjs and clojurescript or have you moved on to something better?

16:19 lynaghk: i heard there was a talk given at clojure west (which i missed sadly) that spoke on making that sort of thing easier with a few tricks but i don't think the talk has been posted yet.

16:26 mefesto: if i have different feature branches of a project being worked on and would like to test them out in another project; is there a version naming scheme that anyone recommends? I was thinking 1.0.0-SNAPSHOT-feature-name

16:26 gfredericks: Raynes for california state senate

16:27 mefesto: he'd have my vote. if i lived out there

16:27 djwonk: any Washington DC area folks in here? I'm about to head to the user group meeting

16:27 Raynes: gfredericks: That was pretty random. :o

16:28 gfredericks: Raynes: mefesto brought it up

16:28 Raynes: Oh, I didn't read that far back.

16:28 I accept your nomination, gfredericks.

16:28 I shall begin campaigning tomorrow.

16:29 nkoza: there is some function in the standard libs equivalent to #(fn [x] true) ? (always returns true, can be useful to replace a predicate)

16:29 Raynes: (constantly true)

16:29 noprompt: Raynes: and i shall help you with flyers, banners, stickers, buttons, and a personal website!

16:29 hiredman: (doc constantly)

16:29 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

16:29 Raynes: Which is amusingly longer, nkoza, but a nicer solution in general.

16:29 Man, hiredman still has me on /ignore? :(

16:30 noprompt: (doc occasionally)

16:30 clojurebot: Excuse me?

16:30 Raynes: It has been like 3 years now.

16:30 noprompt: lol

16:30 nkoza: Raynes: thanks

16:30 bbloom: noprompt: (def occasionally constantly) ; All occasions

16:31 something something something fair dice roll

16:31 noprompt: lol

16:31 pjstadig: somewhat-less-than-usual

16:31 amalloy: well, #(fn [x] true) is more like (fn [] (constantly true)). i assume nkoze actually wanted (constantly true) but included the # in his request just to confuse matters

16:32 nkoza: the # was a typo, sorry :)

16:32 noprompt: whenever would be a fun one.

16:32 hiredman: 3d6+5

16:32 clojurebot: 15

16:33 noprompt: (whenenver some-fn) ;; At some point in the future call some-fn.

16:33 gfredericks: noprompt: why just the future? couldn't calling it in the past be allowed?

16:33 mefesto: (every-now-and-then x)

16:34 noprompt: (every-now-and-then get-a-little-bit-lonely)

16:34 gfredericks: how would that work?

16:34 metellus: gfredericks: not by causality

16:34 noprompt: (at-a-later-date ...)

16:35 pjstadig: gfredericks: don't be disrespecting the arrow of time!

16:35 gfredericks: it's all an illusion!

16:35 metellus: if it was a compile-time thing that could work though

16:35 the compiler finds that and just throws some-fn somewhere

16:36 ToxicFrog: Raynes: I have someone on ignore from like 2008...although to be fair they were an incredibly persistent troll and probably aren't around anymore.

16:36 Client should probably clean up ignores after a year or something.

16:36 mefesto: (defmacro surprise-me [& body])

16:36 pjstadig: gfredericks: that's right, i forgot that Einstein's Theory of Relativity establishes the non-existence of time

16:37 Raynes: ToxicFrog: Totally fair, but to this day I have no idea what prompted the ignoring. Nobody would ever tell me, and he and I have even exchanged smiles on elevators. I sometimes wonder if he is simply forgotten.

16:37 he has*

16:38 I can't help but think of how much we could have accomplished over the years had it been possible to put our snarks together while answering questions.

16:38 hiredman: I saw a nova special once, I'm pretty sure it did

16:39 pjstadig: hiredman: http://amzn.com/B0095XKMS8

16:39 tomjack: dnolen: I've made a couple starts on adding async to clojurescript.test, no success yet

16:40 noprompt: bbloom: well i guess you could have the function do something and then at some random point in time later tell you.

16:40 tomjack: more motivation now that my core.async cljs port gives me a way to convey dynamic bindings

16:40 I got stuck trying to think about what to do about that instead of just hacking it somehow

16:40 noprompt: (defmacro whenever [fn ohey-msg])

16:41 tomjack: now we can hack it somehow (i.e. tester's responsibility to convey clojurescript.test's dynamic vars) and have core.async make it work for us

16:41 hiredman: noprompt: I'm pretty sure there is a ruby library that does that

16:41 ToxicFrog: Raynes: huh. I'd tell you if I knew, but I'm pretty sure that was before my time here.

16:41 noprompt: hiredman: nice.

16:42 Raynes: ToxicFrog: It's very possible and even likely that I was annoying as hell though. I was like 15 at the time.

16:42 ToxicFrog: Oh

16:42 That might do it

16:45 gzmask: /leave #clojure

17:08 djwonk: bbloom: (def random 42) ; 42 chosen at random

17:08 bbloom: djwonk: that was the joke, yes

17:09 djwonk: where is the community-accepted place to say "i'd like to hire a Clojure freelancer for some work?"

17:11 will try the mailing list

17:13 * noprompt imagines someday working with a team of clojurians.

17:13 Foxboron: bbloom, djwonk needs more XKCD

17:13 justin_smith: once you adapt to the elevated smugness levels it is nice

17:14 mabes_: lol

17:14 * noprompt suddenly feels hopeless as reality sets in.

17:14 Foxboron: noprompt, negativity never helps a dream :D

17:15 noprompt: :P

17:15 i'm actually a pretty positive guy.

17:15 gfredericks: the correct group-noun for clojurians is "an IPersistentCollection"

17:15 noprompt: i work with clojure pretty much everyday now at work, just not on a team. :/

17:16 gfredericks: :)

17:31 gfredericks: noprompt: being on a team of people writing clojure pretty much degenerates into macro wars. You have to write macros that somehow trick your opponents' macros into behaving unexpectedly.

17:33 hiredman: feh

17:33 gfredericks: hiredman is apparently not winning

17:33 hiredman: if your team has a 2 inc policy, there is no way you can do that

17:34 (only code reviewed and given two plus ones can be merged)

17:34 gfredericks: that just makes it more challenging

17:36 hiredman: it means at least two other people have seen your macros already, very hard to sneak things in

17:36 hyPiRion: nono, you just team up with other people

17:37 hiredman: horse trading

17:37 of course everyone also has a dec veto

17:44 gfredericks: is there any reason not to create a jira ticket about clojure.walk metadata loss?

17:45 noprompt: so in clojure, team member is just an alias for opponent?

17:45 interesting.

17:45 :P

17:45 hiredman: "review committee member"

17:46 patchwork: This is why we don't use macros : P

17:46 gfredericks: "the other elements of my IPersistentCollection"

17:47 maybe it should be a transient

17:49 noprompt: i want a macro that overwrites a random function in another namespace, then when the function is called randomly executes the body of code given to the macro, suppresses all execptions, and returns nil.

17:50 gfredericks: at macro-expand-time or runtime?

17:50 noprompt: hiredman: that is ruby.

17:50 gfredericks: which would be worse?

17:51 gfredericks: noprompt: I have no idea

17:51 noprompt: worse as in better, as in more evil.

17:51 hmm... in this case probably at run time

17:53 hiredman: (defmacro bad [& body] (in-ns 'foo) `(do ~@body))

17:56 noprompt: (defmacro very-bad [& body] `(do (try (bad ~@body) (catch Exception e#)) nil))

17:59 gfredericks: you don't really need macros for this kind of evil

17:59 just have some top level code that sleeps for 3 hours and then wraps every var in the system to return nil 0.01% of the time

17:59 (in a future perhaps)

17:59 noprompt: haha

18:00 hiredman: gfredericks: the thing with macros is the code in them gets executed when code is compiled, so they don't actually need to be top-level

18:01 so you can hide (bad ...) inside a function, and suddenly the following code is being compiled in a namespace without clojure.core

18:02 tieTYT2: i'm thinking of writing a game's server in clojure. Netty seems like a cool api, but won't I have to intimately understand it in order to use it in clojure since it may have different concurrency concepts?

18:05 hiredman: tieTYT2: how can you have different concurrency concepts? do you mean identity/state management?

18:05 netty (I am pretty sure) doesn't have any of that

18:05 tieTYT2: i'm not sure because I don't know either very well. My impression is clojure is very opinionated on concurrency and state. Netty may violate those opinions

18:06 and I'm afraid if I use netty in a clojure app, it may have unexpected results

18:06 hiredman: so?

18:06 patchwork: https://github.com/ztellman/aleph uses netty

18:06 and is clojure

18:07 tieTYT2: that's reassuring

18:07 hiredman: I don't really understand what you are getting at, if you use one thing you don't understand you are likely to get unexpected results

18:07 let alone two things

18:07 amalloy: hugod: i'm pleased to report that the ritz instructions are now so obvious that i was able to get ritz and nrepl going in just a few minutes, after years of using swank/slime

18:07 tieTYT2: yeah that's true

18:08 but I figure it could take weeks to discover they're incompatible with each other so I thought I'd save some time by asking the question

18:08 looks like they're safe to use together

18:09 hiredman: tieTYT2: clojure is a generally purpose language, it integrates with the jvm, you can use anything else on the jvm with it

18:15 tieTYT2: well I get the sense that if you use a mutable java object with refs, you'll get unexpected results. But you can't really get yourself in trouble if you build a pure clojure app

18:16 hiredman: that is not true

18:16 tieTYT2: which part?

18:17 hiredman: you can easily shoot yourselft in the foot using just clojure

18:17 tieTYT2: oh i see

18:18 hiredman: the only safety is understanding, which is difficult

18:18 nDuff: tieTYT2: ...and Clojure _does_ provide tools that help with management of mutable objects, though just how useful those tools are depend on just how unpredictable the objects' behavior is.

18:19 tieTYT2: ...making access go through agents, for instance, does a fair bit of good for predictability when something isn't changing its state except when poked.

18:19 tieTYT2: ok well i'll learn more about this when i get started, thanks

18:33 tomjack: cemerick: I'm trying to patch clojurescript.test for async test support. I see a few options: 1) rewrite all the dynamic vars into atoms

18:34 2) provide cemerick.cljs.test/bound-fn like this https://www.refheap.com/320114f8f611dbe10d04b8df5 and require people to wrap their async callbacks with it, 3) provide a bit more general bound-fn workaround which allows specifying a list of vars to convey in addition to cemerick.cljs.test's

18:34 or 4) make it the tester's responsibility to convey cemerick.cljs.test's vars in the manner of their choosing

18:34 .. or 5) wait till clojurescript supports binding conveyance

18:34 any thoughts?

18:35 option 1 could be not so bad by writing a custom binding macro that just uses atoms

18:36 6) rewrite clojure.test so that it doesn't use dynamic scope

18:36 :D

18:38 option 3 doesn't make sense, they won't have clojurescript.test's bound-fn workaround in prod to convey vars, so shouldn't do that in tests

18:42 dnolen: it occurs to me that advanced compilation frees us to do some perf tricks around bound-fn

18:43 since we know all the dynamic vars in a program we can just do array lookup

18:44 tomjack: why only advanced?

18:44 bbloom: tomjack: because you can't def new vars in advanced

18:45 tomjack: you know them all apriori

18:45 tomjack: from the cljs compiler's perspective the situation is the same, though, right? you just know that the state you're building up will not be reused later?

18:46 dnolen: bbloom: did you just use a mutable array in your implementation for the var stack?

18:46 bbloom: dnolen: do we care much about non-advanced perf? b/c the real problem is that if dynamic vars are special, redefing from static to dynamic or vise versa will break previously compiled call sites

18:46 dnolen: my implementation was a long time ago and i was much dumber then :-P i don't recall what i did, i think i just ported the JVM code more or less line for line

18:46 dnolen: bbloom: yeah we don't, I'm just thinking about the cheapest operation possible so it won't affect normal usage of dynamic binding

18:48 bbloom: dnolen: is NEVER GETS ANY SLOWER a realistic perf goal? i think that the full persistent maps version of var non-root-values is reasonably fast for a small number of dynamic variables, which is the norm

18:48 rather than getting particularly clever

18:48 the concern (for me) has always been slowing down normal fn calls & constants and the like (aka non dynamics)

18:48 tomjack: personally I'm guessing I'd like to have the same access as now

18:49 I don't know if cljque's use of dynamic vars is a good one, but it's a good example I think

18:49 you probably don't want a PHM lookup every single time you register a callback on a promise?

18:49 eh, who knows, maybe it wouldn't matter

18:49 bbloom: dnolen: see also http://dev.clojure.org/pages/viewpage.action?pageId=950293 which shows that clojure has similar problems to those that we're thinking about in cljs

18:49 dnolen: actually I don't even think we need a stack

18:50 just an array w/ slots for each dynamic var

18:50 bound-fn would clone it

18:50 bbloom: i'm sure i've asked this before, but would prototype lookup chains be good enough?

18:51 this way you could treat the "stack" as js objects you just never modify after create

18:51 lookup would be linear with depth of stack

18:51 generally, bindings are pretty shallow

18:51 unless you're doing `binding on every iteration of a recursion, which isn't shallow, but is also kinda a bad idea :-P

18:52 tomjack: why have the stack?

18:52 bbloom: then bound-fn just needs to alias the current obj pointer

18:52 so object clone cost

18:52 hiredman: you're not allowed to recur across a binding

18:52 bbloom: s/so/no/

18:52 hiredman: actally is that true?

18:52 maybe you shouldn't be, but are

18:53 gfredericks: binding involves a try/finally, so presumably not at the moment?

18:53 dnolen: bbloom: prototype chain idea is clever

18:53 hiredman: gfredericks: ah, good

18:53 gfredericks: but I thought rich was trying to "fix" that

18:53 hiredman: excellent

18:53 tomjack: I see my last attempt actually does have the stack

18:53 hiredman: gfredericks: the fix was to the code that disallowed it, it would do stuff like stop you from loop/recuring inside a finally

18:53 dnolen: bbloom: cheaper for bound-fn since we don't have to clone ... just create new object and set prototype

18:53 lynaghk: noprompt: yes, doing a lot of angular.js + cljs over here; no plans to change, either. I'll be dropping quite a bit of open source stuff in the next month or so to coincide with the release of an iOS angular.js+cljs weather app.

18:54 bbloom: dnolen: i've been saying this for a year now :-)

18:54 hiredman: gfredericks: allowing reucring across bindings and try/catch/finally (with there dynamic extent) is a bad idea

18:54 dnolen: bbloom: heh yeah, but core.async didn't exist then ;)

18:54 bbloom: dnolen: however, forgive me for sucking at communicating for the first 8 months or so of that

18:54 hiredman: so I doubt rich is changing that

18:55 gfredericks: hiredman: oh you mean (try (finally (loop ... (recur))) was disallowed?

18:55 hiredman: yeah

18:55 gfredericks: that's a weird thing to want to do though isn't it?

18:55 hiredman: so the compiler would complain if you put a doseq in a finally

18:55 gfredericks: ooh

18:55 hm

18:55 hiredman: gfredericks: happens all the time for cleaning up a list of resources

18:55 gfredericks: yeah I guess so

18:56 okay cool

18:56 noprompt: lynaghk: awesome. i'll definitely be looking forward to that. hopefully it's right around the time i get back in the angularjs + clojurescript game.

18:56 * hiredman wrote (some of, all of?) the too restrictive patch

18:57 noprompt: lynaghk: the big thing that bothered me was all the clj->js madness and basically ended up writing a lot of wrapper code.

18:57 lynaghk: noprompt: there's not a ton of new stuff, to be honest. Basically, just using native JS data structures from CLJS by implementing a handful of protocols

18:57 hiredman: Juha Arpiainen finally fixed it

18:58 noprompt: lynaghk: which protocols?

18:58 lynaghk: ILookup, ISeq, that kind of thing

18:58 bbloom: dnolen: so in clojure there is only clojure.lang.Var, which is mutably static or dynamic

18:58 lynaghk: so you can say, e.g., (let [{:keys [a b]} your-js-object] ...) and have it just work

18:59 noprompt: so are you using extend-type Object for that sort of thing?

18:59 lynaghk: noprompt: yep.

18:59 bbloom: dnolen: my proposal is an IVar with 3 implementations: 1) the same as clojure for non advanced compilation. 2) DynamicVar for use in advanced compilation where static vars are optimized away via a full-program pass and 3) StaticVar, for still allowing #'foo syntax even after static vars are compiled away

18:59 tomjack: lynaghk: that is evil :P

18:59 hiredman: bbloom: clojure vars can be :static, :dynamic, :const, or a regular var

19:00 noprompt: tomjack: i was just about to say that is what i heard but surely there is a clean way to handle that.

19:00 dnolen: bbloom: yeah I still not interested in bringing in any var semantics - just language support to convey bindings

19:00 lynaghk: tomjack noprompt: what in particular strikes you as evil?

19:00 noprompt: yeah i'd love an explanation on that one.

19:01 tomjack: objects aren't values, values "refuse to help you program imperatively ... that's a feature"

19:01 bbloom: dnolen: even if you ignore #3, you still need a full var impl to support incremental development without having to recompile stale call sites: you need the extra level of indirection that vars provide

19:01 tomjack: imo clojure(script)'s core protocols should also refuse to help you program imperatively

19:02 dnolen: bbloom: ah right

19:02 tomjack: though, I dunno

19:02 dnolen: bbloom: still, likely to just hide that as implementation detail

19:02 tomjack: you can destructure arrays in clojure

19:02 but arrays don't implement IIndexed

19:03 dnolen: tomjack: technically you destructure IndexedSeq

19:03 bbloom: dnolen: happy to implement it without exposing the var functions other than via a hypen prefixed "private" protocol method

19:03 noprompt: lynaghk: well, whenever you make that stuff public let me know. i'm going to be making heavy use of angular here w/in a month.

19:04 tomjack: dnolen: in clojurescript? nth on java arrays does not use IndexedSeq afaik

19:04 noprompt: and, no, i refuse to write raw js.

19:04 :)

19:04 dnolen: bbloom: if you have time, cleanup the patch and I'll take a look!

19:04 tomjack: yes sorry CLJS

19:04 tomjack: thought you were talking about protocols

19:04 lynaghk: noprompt: (shameless plug) there will be an announcement on the Keming Labs mailing list, and probably also the cljs mailing list.

19:05 bbloom: dnolen: i might just bang that out tonight, since i'm sick of having this conversation on loop :-)

19:05 tomjack: I see, there's a special case in seq for js arrays

19:05 dnolen: bbloom: haha, cool

19:05 noprompt: lynaghk: good deal. i'll keep my eye out for it.

19:05 tomjack: well there's a special case in nth too

19:06 dnolen: tomjack: yeah we used to do this stuff via protocols but it's faster to just do it in seq and it also it makes reasoning about dead code elimination simpler

19:07 tomjack: so neither clojure and clojurescript provide any evidence as to whether arrays 'should' implement Indexed

19:07 bbloom: dnolen: heh, my patch is OLD. i can probably redo it faster from scratch

19:08 dnolen: only took me 2ish days the first time & i had no idea what i was doing then

19:08 tomjack: I guess if it doesn't implement IPersistentCollection, it might not be evil

19:09 dnolen: tomjack: in CLJS arrays used implement Indexed, again changed for perf

19:09 tomjack: oh right the fact that they did before is some evidence that they 'should'

19:10 dnolen: the important thing is that nth work on arrays

19:10 hiredman: how is an appeal to authority any kind of evidence?

19:11 tomjack: depends on the authority

19:11 I'm guessing dnolen wrote it so it counts as evidence to me :)

19:11 dnolen: tomjack: heh no, all the protocol stuff was in place long before I did anything

19:12 I've most removed the protocols on natives for code size and perf reasons

19:12 mostly

19:13 tomjack: lynaghk: I retract my claim, as long as equiv and cons throw

19:14 brehaut: dnolen: unrelated cljs q: is there a method apply function / macro in cljs? eg to make (.apply (.-method o) o (to-array seq)) simpler?

19:14 tomjack: or equiv could be identity equality maybe like datomic entities.. :/

19:16 hiredman: tomjack: if equiv is egal, egal for mutable things is identity

19:16 tomjack: is = egal?

19:16 hiredman: rich has said clojure's = (based on equiv, but not when he said that) is an implementation of egal

19:16 technomancy: tomjack: not really

19:16 hiredman: but technomancy disagrees

19:17 technomancy: it's close, but it makes some concessions to convenience

19:17 tomjack: like pcequiv? or what

19:17 ..I need to read that paper

19:17 hiredman: clojure's equality has also under gone some changes since rich said that (it was in one of the blip tv videos)

19:18 technomancy: tomjack: the most obvious is equivalence between vectors and seqs despite them having very different operational behaviour

19:18 tomjack: right, that's what I was thinking of. I think that's due to pcequiv

19:18 technomancy: oh, gotcha

19:18 I'm not familiar with the implementation much

19:19 dnolen: brehaut: is this some interop you're doing?

19:19 hiredman: of course pjstadig disagrees with technomancy to some extent, but he isn't as vocal in #clojure

19:19 technomancy: tomjack: if you are super-pedantic you could say that the presence of the identical? function also disqualifies it

19:19 brehaut: dnolen: someone was wanting it yesterday, and i dont actually use cljs at all, but yes, for interop

19:19 technomancy: err--actually I think the paper specifically makes allowances for "primitive" identity functions, so maybe scratch that

19:19 but things can print differently and still be equal

19:20 dnolen: brehaut: (apply (.-method obj) o seq) should work

19:21 brehaut: dnolen: oh right. cool

19:21 technomancy: I think we can make exceptions for things that are explicitly defined as implementation detail, like the order in which elements of unordered collections print

19:21 but there are other cases where equal things print differently

19:22 dnolen: brehaut: apply is designed to interop w/ regular JS fns

19:22 tomjack: so take datomic entities. consider an operation which takes two datomic entities and returns a predicate of datomic times. ((=?= e1 e2) t) is true if, at datomic time t, the datoms in the extent of the e1 are equivalent to the datoms in the extent of e2 (substituting their entity ids appropriately). if datomic time t has not yet occurred, I suppose it throws or blocks

19:22 brehaut: dnolen: its a little unfortunate that you still have to mention the object twice

19:23 tomjack: so e.g. ((=?= e1 e2) 0) is always true (for non-bootstrap entities) because the extent of any two (non-bootstrap) entities at t=0 is empty

19:23 dnolen: brehaut: well it's not any cleaner in JS :)

19:23 brehaut: (but its also unfortunate that you'd have to do the same thing in js)

19:23 tomjack: what is that? I can't call it 'equality'..

19:25 poindontcare: question, is evaling sufficient for creating classes with gen-class or does one need to do something special?

19:25 tomjack: hmm that has been brewing in the back of my head for a while but now that I say it I realize is all wrong

19:26 bbloom: dnolen: what's the cljs-ism for the JS "in" operator?

19:30 tomjack: 'equal' entities must have the exact same histories/futures, which makes that 'equality' useless

19:31 because almost certainly only identical entities are going to be 'equal'

19:37 Morgawr: as far as running Clojure without a JVM, what viable options do I have? I know of Clojure on CLR (nope) and ClojureScript (great, I use it). I've heard about compiling clojure to scheme and then scheme to C but that sounds very farfectched. There's also clojure-py but the project hasn't gotten any contribution for a while

19:37 what other options are there?

19:56 brehaut: Morgawr: thats an implementation for the three big platforms, two more esoteric / niche platforms, and indirectly one old big platform. there arent really many non-niche / esoteric platforms remaining (objC/cocoa being the obvious one not listed)

19:57 i recall seeing toy implementations for haskell, and c in the past, maybe also objective c, but nothing you'd want to build on

19:57 but your google is as good as mine

19:57 Morgawr: I see, thanks

19:58 hiredman: fine is far better, because it is mine

19:58 mine

19:58 Morgawr: I guess I don't even know what I want myself... it's just that I despise the JVM

19:58 hiredman: you shouldn't

19:58 technomancy: it's great for most things and terrible at a few

19:58 brehaut: despising the JVM is an extremists position that isnt supported by evidence

19:58 Morgawr: it's a cumbersome beast, eats a lot of memory, lots of dependencies, doesn't play well on some Linux systems, etc etc

19:58 hiredman: Morgawr: none of that is true

19:59 Morgawr: what you mean is "I am unfamilier with the jvm"

19:59 Morgawr: maybe

20:00 technomancy: "doesn't play well on some linux systems"?

20:00 Morgawr: the differences between proprietary and non-proprietary jvm implementations are tricky

20:00 at least in my experience when developing Java

20:00 technomancy: don't use anything but openjdk

20:00 brehaut: the eats memory one amuses always me; python backed sites i develop frequently consume more ram than my clojure powered sites

20:00 technomancy: problem solved

20:01 if you got tricked into thinking gcj was an actual thing then you have my sympathy though

20:01 hiredman: the reference jvm impl is openjdk at the moment

20:01 Morgawr: brehaut: I tried to see if I could install the jvm to play with clojure on my headless server and I had to download 300+MB of dependencies with X server and all of that stuff (I don't use X server on a headless server, kthx)

20:01 hiredman: Morgawr: that is a packaging issue

20:01 technomancy: Morgawr: either your package manager sucks, or you weren't paying attention to the x-free variants

20:02 hiredman: on debian based systems there are usually -headless package variants of the jvm

20:02 Morgawr: oh, so Clojure is built with openjdk as reference? That's good to hear, I've always used openjdk and I was speaking only from my Java experience (I love clojure and never had problems with openjdk), so I guess I was wrong with that

20:02 I guess I can give another go at the whole packaging/jvm stuff

20:02 hiredman: you can also go to the oracle website and download hotspot and run it right of the tarball they give you, without installing anything

20:03 nightfly: in debian/ubuntu openjdk-7-jre-headless is probably what you want

20:03 dnolen: bbloom: for .. in ?

20:03 technomancy: there are some issues with the IBM JDK that come up occasionally, but there's no reason to use that unless you work for IBM

20:03 hiredman: Morgawr: no, I mean the jvm reference implementation

20:03 n_b: The only place I have ever had JVM issues is on an RPi

20:03 brehaut: dnolen: key in associativeObj

20:03 Morgawr: I really do love Clojure, I really want it to work out well for me but I'm just a bit taken aback by the whole jvm business, I'm sorry (I'll do more extensive research on the matter)

20:03 bbloom: dnolen: yeah what brehaut said

20:03 anyway, i'm just hacking up a proof of concept of one approach

20:03 so i just js* hacked it for now

20:04 brehaut: particularly useful for key in sparseArray

20:04 hiredman: n_b: most likely due to hard/soft float differences in arm abis

20:04 brehaut: s/for/in context of/

20:04 dnolen: bbloom: hmm I don't think we have anything for that

20:04 bbloom: could probably just be js-contains?

20:05 hiredman: I use oracle's hotspot jvm on my beaglebone (soft float)

20:05 n_b: hiredman: That's precisely it; it's not a platform I'd ever expect to be well supported, so that it works at all is a testament to its versatility

20:05 livingston: I have some ring middle-ware (a friend wrapper specifically) I'd like to have it get some of the config values from a file on the server, except the standard way to build up apps is always with def this and def that, which will cause my compiler will want to read the file at compile time -- what's the best way to not do that?

20:05 dnolen: bbloom: oh right, goog has it

20:05 bbloom: dnolen: oh? what is it?

20:05 dnolen: goog.object.containsKey

20:06 bbloom: ah, ok

20:06 i'll file that away for the future

20:06 in the meantime, hack hack hack

20:07 brehaut: livingston: if you are using compojure, defroutes just wraps routes in a def

20:08 hiredman: livingston: there are a number of libraries for reading configs, carica (from the clojure team at sonian) and environ are two

20:09 livingston: brehaut: those are fine it's the part to wrap the middleware around those that was an issue,... the example I had put all that in a def and then called defservice on that...

20:09 hiredman: I think environ does something config related, I've only ever used carica

20:10 livingston: .. if I avoid keeping the intermediate value and just wrap the code in defservice I'm fine -- I think..

20:10 brehaut: im not familiar with defservice

20:10 livingston: hiredman: oh. great. I haven't seen those, always better than reinventing the wheel - I'll take a look.

20:11 hiredman: carica basically reads clojure maps from files on the classpath and merges them, so you can have an empty map that used for dev testing or whatever, or a map with some default values, and you put the file with the map with the real values on the classpath in production and it uses that

20:12 https://github.com/sonian/carica

20:12 gfredericks: hiredman: you normally have a build step that copies an env-specific "config.clj" onto the classpath?

20:13 hiredman: livingston: but generally having a top level form that does i/o like that is a bad idea

20:13 livingston: yeah I know -- that's why I was trying to avoid it - more importantly I can't even compile it

20:14 hiredman: gfredericks: no, the environment specific config (that overrides the defaults) is written by chef to a known place, and the launcher script always puts that known place in the right place on the classpath

20:14 (for our setup)

20:14 livingston: brehaut: defservice is for ring to create a servelet that will play nicely in tomcat

20:14 hiredman: you certainly could do some kind of build step to pre-brake everything in

20:15 technomancy: hey now http://openjdk.java.net/jeps/118

20:16 technomancy: hiredman: whoa daaaaang

20:16 nice

20:17 hiredman: slated for java 8

20:18 http://mail.openjdk.java.net/pipermail/jdk8-dev/2013-May/002575.html

20:20 tomjack: which is slated for 2014 sometime?

20:21 brainproxy: hiredman: would the implication be that you could introspect a compiled functions parameters list?

20:21 hiredman: brainproxy: if the clojure compiler was extended to emit the attributes

20:22 brainproxy: hiredman: that would be nice

20:22 I was just thinking of that today actually

20:22 I learned a trick for doing effectively that in javascript (at runtime!) the other day

20:22 hiredman: you can currently look at the debugging information (which isn't really exposed through the java reflection api) which tells you the name of locals (and args) and their scope

20:23 brainproxy: https://github.com/michaelsbradleyjr/jonas/blob/master/jonas.js#L1519

20:23 hiredman: so if a local has a scoping starting at 0, then it is likely an arg

20:23 brainproxy: ^ you can use that technique to smartly build "environments" that are not dependent on the position of parameters, but only on their name

20:24 hiredman: gross

20:25 brainproxy: true, but it works like a hose :D

20:25 hiredman: by "environment" you mean a map

20:26 brainproxy: hiredman: sure, or a mori hash-map :)

20:33 Sgeo: So, Clojure/West videos are going online

20:34 Morgawr: wow, takes around a couple of minutes to start a simple repl on my raspberry pi, haha

20:34 and lein takes 5-10 minutes without output when trying to run the repl, not sure if it hangs or if it just takes forever

20:35 hiredman: which jvm?

20:35 dnolen: brainproxy: heh if only JS had real reflection

20:35 Morgawr: hiredman: I think I got the openjvm-headless

20:35 hiredman: the pi is hard float, and last I checked there wasn't a real jvm released for it

20:36 Morgawr: I'm using raspbian, it has hard float packages but I'm not sure if the jvm has been ported to that (probably not)

20:36 tomjack: Sgeo: at infoq?

20:36 brainproxy: dnolen: true that

20:36 Sgeo: tomjack, I assume so, not sure. Saw it on Twitter

20:36 n_b: it's so slow as to not really be worth it Morgawr

20:36 Sgeo: I just want to see the Racket talk >.>

20:37 hiredman: the beaglebone has a bit of an edge, older hardware, better support

20:37 Sgeo: tomjack, https://twitter.com/ClojureWest/status/339344089940099074

20:37 Morgawr: n_b: yeah, probably... what a shame

20:37 tomjack: ah right, trickling out :)

20:38 bbloom: dnolen: ok so there is a blocking sub-issue: the AST doesn't provide any info for differentiating :var from :the-var from :some-thing-that-looks-sorta-like-a-var-and-hijacks-a-common-emit-code-path

20:38 Sgeo: I wonder if #lang clojure would work well on Raspberry Pi

20:38 n_b: I'd love to write my home automation stuff in clj and run it on the Pi, but I think between the limited RAM and my unfamiliarity with JVM it would be a recipe for disaster.

20:38 bbloom: dnolen: for example, (set! some-var 123)

20:38 Sgeo: Although I guess that's not real Clojure

20:38 hiredman: apparently you can install a sof float linux distro on the pi and use the soft float jvm

20:38 http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html#Java

20:38 Morgawr: hiredman: yeah, I had normal debian (soft float) before but it's not going to make any difference afaik

20:38 hiredman: hmm

20:39 dnolen: bbloom: ok, separate ticket+patch for that please

20:39 n_b: Might be slightly better on a ModelBv2 with the 512 RAM

20:39 tomjack: what are things that sort of look like vars?

20:39 Morgawr: and yeah, my model has 256MB of ram so that's also a bother

20:39 bbloom: dnolen: after i finish this hack hack hack proof of concept

20:39 dnolen: bbloom: k

20:40 hiredman: ah, my beaglebone has 512mb

20:40 dnolen: tomjack: bbloom is talking about CLJS compiler internals, vars are any symbol that appears in source in that respect

20:40 n_b: something like a Beaglebone Black as the "core" of the system with RPI endpoints might make more sense

20:40 tomjack: so like a mutable deftype field?

20:41 n_b: or really Arduinos with an ethernet shield for prototyping and some custom boards once everything is solidified

20:41 dnolen: Morgawr: you could always run a CLJS program - V8/Node.js is fast on RPi from what I've heard

20:41 hiredman: https://www.youtube.com/watch?v=QPN2DFrlrYo#t=50s I have a little rover running clojure

20:41 bbloom: org.mozilla.javascript.EvaluatorException: Encountered code generation error while compiling function "39": Program too complex: too big jump offset (cljs/core.cljs#2402)

20:41 Morgawr: yeah, I guess.. although I don't really dig node.js

20:41 bbloom: lol weeee

20:41 :-)

20:42 Morgawr: mine was mostly just some personal interest, normally I use clojurescript for game development (or at least try to) on the browser

20:42 dnolen: heh

20:43 brainproxy: thanks again for reviving mori, seems like a few people are interested :)

20:43 Sgeo: mori?

20:43 brainproxy: dnolen: sure thing, and I'm glad to hear that

20:43 I saw the post on HN as well

20:43 dnolen: Sgeo: CLJS persistent data structures as a JS library

20:43 Sgeo: dnolen, ah, neat

20:44 dnolen: Sgeo: mostly targeting Node.js since it's not a small dependency.

20:44 brainproxy: Sgeo: http://swannodette.github.io/mori/

20:44 Sgeo: Oh, node.js... wake me up when it gets first-class continuations >.>

20:44 brainproxy: Sgeo: it's all pre-compiled so you can just require it or load it with a script tag

20:44 Sgeo: my Cont impl is working

20:44 as is callCC

20:45 and there is a promises-backed variant of both

20:45 pCont, pCont.callCC

20:45 tomjack: brainproxy: clj, cljs, or what?

20:45 brainproxy: tomjack: vanilla javascript

20:45 bbloom: dnolen: ok, so apparently :var has gotten much more tangled up since i last attempted this… :-/

20:45 Sgeo: brainproxy, hmm

20:45 bbloom: dnolen: my hack hack hack solution won't really work without untangling that

20:45 brainproxy: Sgeo: https://gist.github.com/michaelsbradleyjr/5655300

20:45 ^ that is to be refined further in the next day or so

20:46 but it works as is now

20:46 I'm looking now to take a cue from haskell and implement most of the monads as transformers on the Identity monad

20:46 which will help w/ code reuse

20:47 Cont and pCont will thus be ContT applied to Identity and pIdentity, respectively

20:48 tomjack: hah 'pIdentity' I love it

20:49 brainproxy: tomjack: the idea is that the p.. variants are "promises backed", so each step in a monadic computation involves a step across the event loop

20:49 whereas the non p.. are synchronous

20:50 tomjack: I usually call it 'Deref' or 'Future' or something which obscures its similarity to Identity

20:50 Sgeo: brainproxy, have you had any exposure to lenses?

20:50 brainproxy: Sgeo: just a little, I need to study delimited conts a bit more

20:51 I'm fairly certain I can build a reactive layer and lenses layer using shift/reset

20:51 tomjack: but pIdentity is kind of weird, huh, it's an applicative from a monad by baking in a deep join?

20:51 Sgeo: brainproxy, on the topic of delimited conts, have you seen the work by Oleg stating that undelimited conts are bad?

20:51 brainproxy: Sgeo: yep

20:51 tomjack: or is your pIdentity a monad which violates the laws :)

20:52 brainproxy: tomjack: I think it will not violate them

20:52 but the next day or so will tell

20:52 the monad laws are passing fine for State, pstate, Cont, pCont

20:53 tomjack: see for example https://github.com/michaelsbradleyjr/jonas/blob/master/spec/jonas.spec.js#L453

20:54 tomjack: where's pIdentity?

20:54 brainproxy: haven't written it yet

20:54 :p

20:54 i'm doing some refactoring

20:55 right now I just have some monads in p and non-p flavors

20:55 need to move to transformers that use p and non-p identity

20:55 brehaut: brainproxy: we need to know when you have P and NP being equivalent

20:55 brainproxy: brehaut: different p and np

20:55 :D

20:58 ohpauleez: Is there a way to reflect on the nREPL server?

20:58 to probe it for its middleware or commands it responds to?

20:59 Morgawr: guys.. what's the fundamental difference between apply and reduce? I mean, I get that apply is called on a list of parameters + a collection and reduce is called on val + collection (or just a collection) but I don't get the fundamental difference

21:00 gfredericks: welp

21:00 this came up a couple days ago

21:00 amalloy: &(reduce (partial list '+) [1 2 3 4 5])

21:00 lazybot: ⇒ (+ (+ (+ (+ 1 2) 3) 4) 5)

21:00 amalloy: &(apply (partial list '+) [1 2 3 4 5])

21:00 lazybot: ⇒ (+ 1 2 3 4 5)

21:00 ohpauleez: Morgawr: Apply takes a sequence of items (like a vector, seq, or list) and calls the function as if those args were passed into it

21:00 it's used a lot with functions that take varargs

21:01 * gfredericks was going to tell a story but realized that was silly

21:01 ohpauleez: reduce is used to build values up, or reduce them down

21:01 Morgawr: I see, thanks, that actually makes sense

21:01 ohpauleez: You see reduce a lot to build up a new map or vector, or to extract a single result (like reducing addition)

21:02 gfredericks: (apply foo coll) vs (reduce foo coll) -- in the former foo is called one, in the latter many times

21:02 in the former it's called with many args; in the latter with 2

21:02 ohpauleez: &(reduce conj [] '(1 2 3 4 5))

21:02 lazybot: ⇒ [1 2 3 4 5]

21:03 Sgeo: &(apply conj '(1 2 3 4 5))

21:03 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IPersistentCollection

21:03 Sgeo: That... wasn't quite the error I was hoping for

21:03 Morgawr: so, I should be using apply when dealing with a function that takes all the parameteres from the collection, and reduce when I want to call the function "iteratively" on pairs of parameters?

21:03 ohpauleez: &(apply conj [] '(1 2 3 4 5))

21:03 lazybot: ⇒ [1 2 3 4 5]

21:04 ohpauleez: (shhhh it works because of conj magic)

21:04 gfredericks: Morgawr: not really on pairs -- with reduce, the first argument is going to be the return value of the last call

21:04 livingston: I know in some variants of lisp reduce + is far faster than apply + especially for long lists

21:05 Morgawr: I see, it makes sense now, thanks

21:05 Sgeo: &(reduce + [1 2 3]) is the same as (+ (+ 1 2) 3) I ... think

21:05 lazybot: ⇒ 6

21:05 amalloy: livingston: in clojure i think it's quite likely that apply + is faster

21:05 well

21:05 ohpauleez: &(reduce (fn [[accum new-value]] (str accum " :: " new)) "START" ["one" "two" "END"])

21:05 lazybot: java.lang.RuntimeException: Unable to resolve symbol: new in this context

21:05 ohpauleez: &(reduce (fn [[accum new-value]] (str accum " :: " new-value)) "START" ["one" "two" "END"])

21:05 lazybot: clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox10042$eval13881$fn

21:05 ohpauleez: womp

21:06 Also, that's a bad example haha

21:06 amalloy: hm. no, that's not true. i spoke hastily

21:06 gfredericks: coming up with good examples for this is hard

21:06 amalloy: that's why i just use my (partial list '+) example

21:06 i think it's a pretty good visualization of the alternatives

21:06 tomjack: brainproxy: looks pretty cool, with mori+wisp+that would be interesting

21:06 ohpauleez: amalloy: At one point in Clojure's history, apply was faster

21:06 brainproxy: tomjack: wisp?

21:06 ohpauleez: I'm not sure if it's still the case

21:06 gfredericks: (reduce #(hash-map :first %1 :second %2) [1 2 3 4])

21:06 ,(reduce #(hash-map :first %1 :second %2) [1 2 3 4])

21:06 clojurebot: {:first {:first {:first 1, :second 2}, :second 3}, :second 4}

21:06 brainproxy: tomjack: oh right

21:07 amalloy: ohpauleez: are you sure? i think apply has always just delegated to reduce

21:07 tomjack: but only if I can't convince someone to switch from js to cljs, which happens to be true :)

21:07 brainproxy: tomjack: I'm trying to get the core parts to a place where I can write a really killer mDo

21:07 livingston: yeah usually the apply form has more list foolery to do and ends up using the variadic (sp?) form of the function - the compiler can't be much help there, but with + for example you get the more effecient two argument form

21:07 amalloy: for sure, (+ a b c d e) is faster than (reduce + [a b c d e]), because it inlines well, but using apply loses that

21:08 brainproxy: tomjack: I dont' have macros, but by dogfooding some "power tools" within the lib, I can a very slick monadic "do" like thing working, I'm fairly confident

21:08 can *get a...

21:08 Sgeo: Monadic do in Javascript?

21:08 If it looks nice, that would make me happy.

21:08 brainproxy: Sgeo: yes, basically

21:08 it will look okay

21:09 not "make you dance for joy" quality, but pretty decent

21:09 Sgeo: oh

21:10 brainproxy: and for the "left-hand side" stuff, a coworker is writing a parser so can you use clojure-standard destructuring syntax

21:11 "{y z :as m}", function (x) { mReturn { y: 7, z: "eight" } }

21:12 that will 'just work', in the context of a "program" you pass to say pState.mDo

21:12 amalloy: that must require eval, right brainproxy?

21:12 brainproxy: amalloy: nope, zero use of eval

21:13 the initial version is compiled using PEG.js; to be replaced in the near-ish future by a parser that's built up using the jonas API itself

21:13 i mean initial version of the destructuring syntax parser

21:14 the "problem" with the PEG.js version is that it consists of a *lot* of braindead js code

21:14 no eval, but bloats the lib

21:15 above I should have `... return mReturn ...`

21:15 forgot the js return

21:15 amalloy: and also parens around {y:7,z:"eight"}, i imagine

21:16 brainproxy: amalloy: lolz, yep

21:16 typed it out too quickly in irc

21:18 the thing that will actually make jonas particularly wortwhile is combining it with mori

21:18 tomjack is right about that

21:21 I would love to use clojurescript on the web client side of things, but for various reasons that's not going to happen... so... I'm aiming to create something that will make dev'ing highly concurrent vanilla js programs more pleasant

21:30 tomjack: brainproxy: yeah, looks very cool

21:33 brainproxy: tomjack: thanks, lots to do, hopefully in the very near future it will be mostly useable with some examples, etc.

21:43 tomjack: hmm, async test https://www.refheap.com/b83fa0862b53ae255094a92ee

21:45 with an interface like this, even with a good bound-fn in cljs, users will have to remember to use it in order for their tests not to break

21:45 even if they don't use dynamic vars in their async code at all

21:50 new project: rewrite clojure.test

21:51 ..though if you stick to core.async you won't have to remember, just if you do a manual setTimeout or drop a fn into angular or something

21:54 livingston: I'm trying to use friend-oauth2 with google, and it shows the "allow access" button and takes me to the call back page which bounces me to auth page over and over anyone seen anything like that before?

21:55 it's like friend doesn't recognize the authentication

22:14 tshauck: Hi, how could I put multiple requires into one statement in a file... I keep getting an error that lists inside prefix names must not contain periods

22:14 gfredericks: (:require [foo.bar :as baz] [bang.bazoozle :as flamboyant])

22:16 usually not enough or too many square brackets is what trips people up

22:16 tshauck: gfredericks: cool, thanks, I was doing (:require [[foo.bar :as bar][bang.boo :as boo]]) so ya... too many

22:29 livingston: anyone know friend / friend-oath2? I seem to get the callback after authenticating but then my server (presumably friend) kicks the request back out with a 302? right back to reauthenticate

22:37 bbloom: hmmmm how exactly do tagged literals & metadata interact? i wonder...

22:39 (meta (binding [*data-readers* {'foo identity}] (read-string "^:bar #foo []")))

22:39 tomjack: they interact as you'd expect I think

22:39 bbloom: ,(meta (binding [*data-readers* {'foo identity}] (read-string "^:bar #foo []")))

22:39 clojurebot: {:bar true}

22:39 bbloom: ,(meta (binding [*data-readers* {'foo identity}] (read-string "^:bar #foo 123")))

22:39 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

22:39 tomjack: oh, I was thinking of ##foo bar

22:39 er, ##foo bar baz

22:39 bbloom: ,(meta (binding [*data-readers* {'foo identity}] (read-string "#foo ^:bar 123")))

22:39 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

22:39 bbloom: ,(meta (binding [*data-readers* {'foo identity}] (read-string "#foo ^:bar []")))

22:39 clojurebot: {:bar true}

22:39 bbloom: seems to work either way

22:40 tomjack: with identity, yeah

22:41 bbloom: oh yeah… hmm

22:41 tomjack: db/fn for example will likely destroy inner meta, and maybe explode on outer meta ?

22:42 bbloom: ,(meta (let [discard #(with-meta % nil)] (binding [*data-readers* {'foo discard}] (read-string "#foo ^:baz []"))))

22:42 clojurebot: nil

22:42 bbloom: ,(meta (let [discard #(with-meta % nil)] (binding [*data-readers* {'foo discard}] (read-string "^:bar #foo []"))))

22:42 clojurebot: {:bar true}

22:42 bbloom: neat.

22:46 tomjack: cemerick: https://github.com/tomjack/clojurescript.test/compare/draft-async

22:46 bbloom: so you're stuck on that sub-issue?

22:46 cemerick: tomjack: I'm hyper-occupied; maybe open an issue or start a thread on the cljs list?

22:47 bbloom: tomjack: just don't have the mental capacity today

22:47 cemerick: tomjack: thanks, though, the URL sounds interesting :-)

22:47 bbloom: naming help please: what's the opposite of a "composite" datatype in clojure? my best right now is "scalar", since "atomic" is so overloaded. but it seems to me like the opposite of "scalar" is "vector" which is also overloaded….

22:47 tomjack: cemerick: no prob, just thought you'd be interested. I'll post maybe later, needs more thought/work

22:47 bbloom: either way, if you had {:foo :scalar} and {:foo :vector}, what would :foo be better as?

22:47 :type-type :-)

22:48 or rather {:foo :composite}

22:48 gfredericks: bbloom: I've heard of scalar used to mean this quite a lot

22:49 bbloom: gfredericks: ok cool. so then do you also have a name for the "enum" so to speak?

22:49 gfredericks: though I guess now that I think about math vectors it doesn't really capture the same concept :/

22:49 in linear algebra scalars are not just components of vectors but quantities by which you can "scale" them

22:50 which makes me like atoms a lot more but it is too overloaded like you say

22:50 bbloom: yeah, my linear algebra was at one point pretty good, hence the discomfort with the name collision

22:50 i'm much more concerned with what you would call the set #{:scalar :composite}

22:50 b/c i have no idea lol

22:51 gfredericks: the universe?

22:51 bbloom: no, not the set of objects whos types are in the set of scalars and composites

22:51 the literal set of :scalar and :composite, haha

22:51 classic indirection error ;-)

22:54 TimMc: Oh, it is clearly a :composite.

22:54 Duh.

22:54 * bbloom facepalms

22:55 bbloom: enum SomethingHere { SCALAR = 1, COMPOSITE = 2 }; // help me :-)

22:55 tomjack: structure?

22:56 bbloom: {:structure :scalar …} and {:structure :composite …} hmm maybe

22:56 gfredericks: type categories?

22:56 tomjack: (is (false? (structure? scalar))) (is (true? (structure? composite)))

22:56 gfredericks: there's some meta thing going on here is there not?

22:57 bbloom: if you called them "categories" then you'd have the same problem when you chose another dimension by which to partition. really it's the name for one category of categories

22:58 tomjack wins for now, since my asking this question is really just because i am avoiding the work of actually writing code, but let me know if anybody has any better ideas :-)

22:59 tomjack: or the complement, simple?

22:59 is it basically one/many or no?

23:08 cmajor71: bbloom: {:structure :discrete …} and {:structure :composite …} ?

23:09 bbloom: cmajor71: hmm maybe

23:09 TimMc: &(apply str "structure-" (repeatedly 4 #(rand-int 10))) ;; bbloom

23:09 lazybot: ⇒ "structure-4983"

23:10 tomjack: is a vector not discrete?

23:11 bbloom: i think i'm gonna get around the problem by cheating: I only really need to know :list, :vector, :map, :set, or not one of those… so nil is a perfectly fine value for :composite :-P

23:12 cmajor71: tomjack: I was going from discrete in "individual" sense

23:13 bbloom: words: there are simultaneously too many and too few of them.

23:13 gfredericks: also characters?

23:17 tomjack: should core.async/{put!,take!} in cljs automatically bound-fn the handler?

23:17 hmm, well, the clojure versions don't, so I guess not..

23:18 TimMc: bbloom: Atomicity

23:19 HowManyPrimitivesThisThingCanBeMadeOf

23:19 bbloom: ....Factory

23:19 gfredericks: if you want to make it look enterprisey, camel-case it

23:20 bbloom: ThatIsWhyIWriteAllMyContractsLikeThisAndSimplyIncreaseMyRates

23:20 gfredericks: it's like speaking in a particular accent

23:21 TimMc: ⟜-hipsters-use-kebab-case-

23:31 sinistersnare: might sound stupid, but how do i run a clojure file from the command line? i have this code http://bpaste.net/show/IgFjcHOzkKWt3R72Kx6Y/ how do i run it from the command line?

23:35 amalloy: $google clojure shebang

23:35 lazybot: [Clojure Programming/Tutorials and Tips - Wikibooks, open books for ...] http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips

23:35 n_b: sinistersnare: Does `clj filename.clj` not work?

23:36 bbloom: sinistersnare: if you don't need a shell script for some other reason, you're better off opening `lein repl` and using load-file or whatever keyboard shortcut your editor provides for that :-)

23:37 sinistersnare: i dont think a shebang works in windows? and clj is not recognized as a command

23:37 i have the clojure folder on my path

23:37 how do i install that command?

23:37 bbloom: sinistersnare: https://github.com/technomancy/leiningen

23:38 sinistersnare: i use leiningen, but i want to try out ahead of time compilation, not through an interpreter

23:38 bbloom: lein can produce a jar for you with a main function that you can run with the java -jar command

23:39 sinistersnare: but what if i dont have a main funtion? like with the code i put up

23:40 bbloom: sinistersnare: wrap lins 30 to 39 in a main fn

23:40 sinistersnare: bbloom: ok

23:40 bbloom: see the lein docs for how that works

23:41 sinistersnare: bbloom: i know indentation is bad, but this? http://bpaste.net/show/y1vrG8RAvqy1bTsTma3z/ ok ill check the docs

Logging service provided by n01se.net