#clojure log - Aug 26 2012

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

0:11 synfinat_: any book recommendations for clojure newbie? I know C/Perl/Ruby and some JS/C++. read the first chapter of the Joy of Clojure and I pretty sure I'm more confused then when I started.

0:11 casion: Clojure Programming or Programming Clojure

0:11 synfinat_: cool, i'll take a look at those

0:11 casion: if you're more used to ruby, I'd think clojure programming is probab ly better

0:12 synfinat_: perfect

0:12 casion: for me, being used to C, I've found more benefit in programming clojure

0:12 just my opinion, they're both very good books

0:12 synfinat_: we'll i'm equally fulent in those first three, although seems clojure is closer to ruby

0:15 gfredericks: clojurebot: stuartsierra is authoritative enough

0:15 clojurebot: Ik begrijp

1:09 emezeske: $findfn 1 1

1:09 lazybot: [clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/time clojure.core/dosync clojure.core/long clojure.core/short clojure.core/+ clojure.core/* clojure.core/with-loading-context clojure.core// clojure.core/doto clojure.core/unchecked-... https://www.refheap.com/paste/4634

1:09 emezeske: $findfn [1 1] [1 1]

1:09 lazybot: [clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/list* clojure.core/time clojure.core/dosync clojure.core/lazy-cat clojure.core/sequence clojure.core/rseq clojure.core/with-loading-context clojure.core/vec clojure.core/concat cloju... https://www.refheap.com/paste/4635

1:09 emezeske: $findfn inc 1 5

1:09 lazybot: []

1:09 emezeske: $findfn 1 inc 5

1:09 lazybot: []

1:09 emezeske: $findfn [inc 1 5] 5

1:09 lazybot: [clojure.core/last clojure.core/peek]

1:12 emezeske: Is there a clojure.core function that, given a function and a number, composes that function recursively that many times?

1:12 E.g. (whatever inc 3) -> (inc (inc (inc %)))

1:15 Actually, it doesn't have to return a function, it would be fine if it just performed that operation N times: (whatever inc 3 5) -> 8

1:16 metellus: something with iterate, probably

1:18 emezeske: Yeah, (nth (iterate inc 5) 3) does the trick. That's the most concise I've come up with

1:21 pandeiro: emezeske: repeatedly doesn't do it?

1:22 emezeske: pandeiro: No, I want the initial arg to be threaded through, so the result of the first function is fed to the second, etc

1:24 pandeiro: emezeske: yah nvm, i was confusing with iterate anyway

1:25 emezeske: I think maybe it's not a common thing to want to do

1:25 amalloy: emezeske: it's common enough, and iterate is the right answer

1:26 if it galls you for some reason, you can do something silly like ##((apply comp (repeat 5 inc)) 1)

1:26 lazybot: ⇒ 6

1:27 emezeske: Heh, no gall for me. I just wanted to make sure I wasn't missing a better way to do it.

1:27 I just had that inkling that maaaaybe c.c had composed that already :)

1:32 technomancy: (apply comp (repeat inc 5)) is clearer imo

1:33 maybe it's just me

1:34 amalloy: some of that's because of the awful argument order for nth

1:34 like (->> 1 (iterate inc) (nth 5)) would be pretty nice

1:53 Sgeo: How often does jimduey come here?

1:56 grisu:

1:57 emezeske: Sgeo: Is that his irc nick?

1:57 Sgeo: Yes, apparently.

1:57 At least it was when he msg'd me a while ago

1:58 emezeske: Sgeo: I guess I don't know how often he's here, but I can say that I can't remember the last time I saw him talk

2:01 amalloy: $seen jimduey

2:01 lazybot: jimduey was last seen quitting 1 day and 6 hours ago.

2:39 Sgeo: I hate protocols.

2:39 Suppose I make a library with protocols, and allow users to extend stuff via the usual way to do that with protocols.

2:40 Then I discover use cases which require multimethods. I switch my code over, but that breaks user code that's expecting a protocol-based system.

2:41 Raynes: You hate protocols because you don't know when to use them vs multimethods?

2:42 Sgeo: Because multimethods can generally do the things protocols can do as far as I know (although a bit less statically-safe in some cases?), but they're not interoperable (again, as far as I know, I'm not that familiar with Clojure)

2:43 Raynes: Protocols are like typeclasses.

2:47 Sgeo: Haskell-style typeclasses, even with multiparamtypeclasses (which protocols are not like) are insufficient as far as I'm concerned

2:48 amalloy: so...don't use them

3:02 magopian: it seems it's not possible to use "apply" with "or", how would i go about that?

3:02 amalloy: &(doc some)

3:02 lazybot: ⇒ "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

3:02 magopian: (i'm mapping a function to a seq, which returns a seq of booleans, and i need to "or" them)

3:02 ah :)

3:02 sure, thanks amalloy :D

3:03 (should have thought about that... :)

3:05 Sgeo: &(apply (partial some identity) '(true true false))

3:05 lazybot: clojure.lang.ArityException: Wrong number of args (4) passed to: core$some

3:06 Sgeo: &((partial some identity) '(true true false))

3:06 lazybot: ⇒ true

3:06 Sgeo: I'm ... not entirely sure what I was thinking

3:07 Oh, that some took a variadic amount of arguments as though it was or

3:12 antares_: scalabl3: I figured it out. There were two issues where the Java client could use more helpful error messages but it works now. 1.1.0-SNAPSHOT has a function to connect to Couchbase with bucket/username/password.

3:13 Cr8: I suppose I ought to dogfood that

3:24 oh

3:24 I can't spell.

3:27 antares_: cool, got my project using the couchbase connection now :)

4:09 magopian: stack overflows happen when there's non tail recursive calls, is that right?

4:10 i have found what i believe is a solution to the problem 89 of 4clojure, but it stackoverflows, and i don't see how to fix that :/

4:10 the problem: http://www.4clojure.com/problem/89

4:11 my solution: https://friendpaste.com/7QiF9pQ1oe3J5KgTEKwDII

4:12 Sgeo: Do note that Clojure isn't inherently tail-recursive, although there are ways around that

4:24 Cr8: magopian: the stack will overflow even if your recursive calls are in tail position

4:24 you have to explicilty use (recur) to avoid stack blowup

4:25 magopian: oh really? didn't know that

4:25 nice to know ;)

4:25 i can't see a way to use recurse with my actual solution, will have to think about something new :/

4:26 Cr8: (recur) is basically: switch in these values and GOTO the last recur point

4:26 which is either the top of the fn or the nearest loop

4:26 Sgeo: Cr8, too bad it can't also be used to effectively GOTO a different function

4:27 Cr8: that's the reason for recur

4:27 if you could jump to another function that way then you could just do actual tail call elimination

4:28 michaelr`: good morning

4:29 Cr8: magopian: perhaps you can wrap it up with trampoline

4:29 http://clojuredocs.org/clojure_core/clojure.core/trampoline

4:41 magopian: Cr8: i doubt it, but i'll try ;)

4:43 Raynes: Sgeo: That's what trampoline is for.

6:01 Cr8: aw, can't use future on 4clojure =P

6:31 Sgeo: Cr8, o.O why not?

6:31 Cr8: i don't knwow

6:32 doesn't matter, my solution was wrong anyway

6:32 Sgeo: TryClj doesn't like it either

6:32 java.lang.SecurityException: You tripped the alarm! future-call is bad!

6:32 Clojure>

6:33 I think if I made a ClojureNomic, I might want to make my own sandbox

6:33 But, I'm fairly convinced that newLisp is a better language for a nomic than Clojure

6:33 And it's now starting to sink in that "better for a codenomic" != "better general purpose language"

6:34 Raynes: Cr8: futures are not allowed because they use threadpools which the sandbox cannot control and thus can easily be used to produce threads that are not bound by the timeout.

6:34 Sgeo: I assume you could build your own futures based on promises + Thread. and start.

6:35 erm, .start

6:36 Cr8: I would expect that Thread. would also be a no-no

6:36 Sgeo: Cr8, works for me in TryClk

6:36 erm, TryClj

6:37 Cr8: hm. Does it keep track of the threads you start and forcibly stop them?

6:38 Sgeo: No idea

6:40 Crud, I don't think TryClj likes macros.

6:40 Raynes: Cr8: Yes.

6:40 Sgeo: No biggie, my-future can take a function of 0 arguments instead.

6:40 Cr8: neat

6:42 I guess that's why agents are also bad

6:42 since they use a threadpool that the sandbox doesn't manage

6:42 Sgeo: (defn my-future [f] (let [p (promise)] (.start (Thread. #(deliver p (f)))) p))

6:43 Note that my-future is a function that takes in a function, rather than being a simple macro

6:43 So (my-future #(+ 1 1)) instead of (future (+ 1 1))

6:55 Cr8: whee, got it

6:55 * Sgeo vaguely wants to know if my-future helped

6:56 Raynes: I doubt it.

6:57 You can't define macros on 4clojure, and he said his solution was fundamentally incorrect anyways.

6:58 Sgeo: my-future isn't a macro (specifically for that reason), but yeah, fundamentally incorrect means I'm probably not helpful

7:01 Raynes: Oh, right.

7:01 I didn't mean to imply you were being unhelpful.

7:03 Sgeo: I should make a macro that writes macros that merely deposit their body into an anonymous function and call some other function with that function

7:03 Although I tried to write a macro-writing macro in CL once, it didn't work out too well

7:04 Also, I'd need to consider the role of arguments

7:09 I still need to try to set up a sane Clojure environment on my comp

8:32 jml: how would I make a function that takes a filename and returns a lazy sequence of its lines and that then closes when the sequence is exhausted? Using with-open seems to close the file too soon.

8:33 tomsw: I get a ClassNotFoundException for com.sun.jdi.VirtualMachine whenever I try running lein ritz

8:33 does anyone know how to fix this with lein2?

8:42 ah, realised that JAVA_HOME was pointing at the Oracle jdk but that /usr/bin/java was still pointing at the OpenJDK one.

8:58 hyPiRion: Man, common lisp's format (cl-format) is like a language in itself.

8:58 ,(require 'clojure.pprint)

8:58 clojurebot: nil

9:01 hyPiRion: ,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 2 "cow" 3 "pig")

9:01 clojurebot: "Two cows and three pigs."

9:01 hyPiRion: ,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 0 "cow" 3 "pig")

9:01 clojurebot: ""

9:01 hyPiRion: ,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 2 "cow" 0 "pig")

9:01 clojurebot: "Two cows"

9:01 Bronsa: wtf

9:02 Sgeo: Oh cool, Clojure has a cl-format thing

9:02 hyPiRion: ,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 2 "cow" 1 "pig")

9:02 clojurebot: "Two cows and one pig."

9:02 Sgeo: That's one less thing from CL I'll miss

9:02 hyPiRion: Sgeo: I was so happy when I found it.

9:03 Sgeo: Things I'll still miss: No JVM, CLOS possibly (not sure), condition system absolutely.

9:04 Not setf as such, but it would be nice to have a functional equivalent... instead of mutating something it could give a modified copy

9:06 hyPiRion: Sgeo: I believe multimethods is more flexible than CLOS

9:06 Though I don't know if the efficiency is as nice.

9:06 Sgeo: hyPiRion, I believe that they're fakable at least a little in CLOS

9:07 hyPiRion: Yeah, probably.

9:07 It's completely doable, so.

9:08 Sgeo: Have a regular function that transforms its arguments and then calls a generic function, with a result as the first argument and passing through rest of the args. Methods on that function use eql specializer on first argument,

9:11 Anyways, there's an easier way to write domonad

9:11 At least I believe so

9:12 Oh, I'd also need to handle :when and :let

9:21 xeqi: monad comprehension?

9:23 * Sgeo was thinking of writing the macro such that expands into a bind of a value and a lambda containing domonad

9:28 Sgeo: I'm starting to see that it's fine as it is

9:29 hyPiRion: heh

9:31 Sgeo: I'm not entirely sure why this person uses symbol macros and the like when, afaict, dynamically-scoped variables would work fine.

9:32 gfredericks: this person?

9:33 Sgeo: https://github.com/clojure/algo.monads/blob/master/src/main/clojure/clojure/algo/monads.clj

9:33 Konrad Hinsen

11:02 duck1123: I'm trying to use enlive in a test. I need to find the elements with a data-id attribute and extract those values. I know how to select the elements with the attributes, but how do I get the values from there?

11:08 looks like I can just do (map #(get-in % [:attrs :data-id]) elts) but is there a better way?

11:08 Sgeo: "algo.monads: Might work as-is! Trivial. Hey, when was the last time you saw 'trivial' and 'monads' in such proximity?"

11:08 ^^a discussion of porting various libraries to ClojureCLR

11:09 cshell: duck1123: don't you just return the same thing that you select by?

11:09 or just identity?

11:11 duck1123: If I do (select doc [(attr? :data-id)]) it returns all the elements, not the attributes

11:14 cshell: hmm, yeah mapping over those is probably the way to do it

11:15 I thought there was another selector but i guess I was wrong

11:15 duck1123: I didn't really find anything prettier, probably because that's an easy enough op

12:00 michaelr`: hello

12:01 _ulises: 'lo michaelr`

12:02 michaelr`: 'sup

12:02 _ulises: not much, you?

12:03 michaelr`: i'm building something to scaffold admin interfaces

12:03 _ulises: for?

12:03 clojurebot: for is not a loop

12:03 _ulises: indeed not

12:03 michaelr`: for websites

12:03 web apps

12:03 you know, the crud stuff

12:04 _ulises: michaelr`: are you targeting noir by any chance?

12:04 michaelr`: well, compojure

12:04 _ulises: cool

12:04 michaelr`: i hope so

12:04 let's see in a few days :)

12:05 _ulises: looking forward to it as I have a small project in the backburner and I dread writing the crud bits myself ;)

12:06 michaelr`: heh

12:19 hyPiRion: Alas, my attempt to get the computer project at my university to make a Clojure machine failed.

12:19 nvy: ,(.set #'*ns* 0)

12:19 clojurebot: 0

12:19 nvy: ,(+ 1 1)

12:19 clojurebot: 2

12:19 nvy: nice

12:20 Frozenlo`: hyPiRion: A clojure machine? You mean directly hardware, no jvm?

12:20 ticking: hyPiRion, that would have been pretty nice, but isnt the jazelle kinda a clojure machine^^? Btw we build a machine geared towards lisp in our batchelor project^^.

12:21 hyPiRion: Frozenlock: yes, direct hardware.

12:23 vedm: wn

12:23 hyPiRion: ticking: Kind of, but it's not running on "bare metal".

12:23 Cool that you get to build a lisp-machine though.

12:24 ticking: hyPiRion, yeah most of the stuff is microcode in the arms^^. Sadly its not a real lisp machine, it is done with lisp in mind but so far I had no luck to lobby for hardware concurrent garbage collection ^^

12:25 hyPiRion, semantically it is more of a erlang machine with s-expressions anyway ^^

12:25 hyPiRion: That's really sweet.

12:28 I know people actually built a LISP machine 4 years ago here. Feels like I missed the sweet spot to live by 4 years

12:28 /s/to live/to be born

12:29 ticking: hyPiRion, yeah we wanted to do a manycomputer cpu, the team before us build one, so we decided to do it again but better ;P

12:29 hyPiRion, do you mean the Igor?

12:29 hyPiRion: ticking: yes

12:30 ticking: hyPiRion, awesome, I lobbied fo using it as the basis for our many core approach, slap on a bunch of routers, scale it across a frew fpga. Got scraped because of gatter limitations. Guess what our classical von neuman uses as much gatters.

12:32 hyPiRion: ticking: heh

12:33 ticking: hyPiRion, I'm more of a lisp guy, but have you seen the greenarray chips^^?

12:34 hyPiRion: ticking: Nope

12:35 ticking: hyPiRion, http://www.greenarraychips.com/ pretty awesome stuff, they put 144 super tiny and reduced forth machines onto one chip

12:36 hyPiRion: wow, that's neat

12:36 ticking: hyPiRion, 100gops at 1 wat I think ^^

12:36 hyPiRion, I wish we had that for lisps ^^

12:37 hyPiRion: ticking: I wish we had a lot for lisps.

12:39 I realized some time ago that if I'm just going to wish for stuff, I'll just sit on my ass and do nothing. So I figured I'll try and make some of the stuff I wish for.

12:39 ticking: hyPiRion, yeah only approach that works ^^

12:41 * Sgeo thought of an impure way to do something interesting, just trying to figure out if there's a pure way.

12:41 hyPiRion: Sgeo: Go on.

12:42 Sgeo: Giving the result of a function (such as Seesaw's listen) to a function passed into that function

12:42 I see how to do that via promises. But if there were a pure way to do that, that would be ... interesting

12:42 gfredericks: O_O

12:43 Sgeo: can you describe that less abstractly?

12:43 ticking: Sgeo, you mean a y-combinator^^?

12:43 Sgeo: ticking, along those lines, I think.

12:43 hyPiRion: Yeah, sounds like some combinator of some sort.

12:43 Sgeo: (listen) takes some arguments and a function, and installs the function as an event handler.

12:44 ticking: you want to use the return value of listen in the event handler

12:44 Sgeo: Yes

12:44 gfredericks: I don't think you can do that purely

12:45 assuming you can't control how listen behaves

12:45 ticking: formal-proof time *yay*

12:45 gfredericks: also assuming you consider promises to be impure :)

12:46 Sgeo: I am

12:46 hyPiRion: promises aren't impure :(

12:46 ticking: Sgeo, the problem I think you have is the impurity of listen

12:46 gfredericks: yeah I qualified because that seems a bit ambiguous

12:46 yeah listen is for side effects

12:47 Sgeo: hyPiRion, a promise has a mutable state: Whether or not it's been delivered, and if delivered, what its value is.

12:47 gfredericks: I don't think promises are really less pure than lazy seqs

12:47 you can implement a promise with a lazy seq I think :)

12:48 ticking: if listen were pure, there could be two scenarios. The return value is of relevance to the calculation listen does, thus without initializing it in the handler function results in a contradiction, you would have to evaluate it, in order to evaluate it

12:48 gfredericks: sort of; this is all really hairy :(

12:48 Sgeo: Hmm, I don't think Haskellers consider laziness to be impure, although the implementation is.

12:48 ticking: the second option is, it doesn't have any effect on the calculation, in which case it doesn't matter if you actually provide it

12:49 Sgeo: ticking, the return value can be of relevence without needing to have the entire thing computed.

12:49 Maybe listen does something like conj'ing a 1 onto its return value, in a lazy structure.

12:50 ticking: Sgeo, yeah lazyness makes it tricky, I was reasoning in lambda calc

12:50 but still the same rule applies, even if you have a lazy sequence, just because the first element is the same, doesn't mean the rest will be

12:51 so you'd do something even worse than impurity, defining equality based on the stuff you have extracted so far from the lazy entity

12:52 the only way this is of relevance is that the handler is somewhere stored to be called later, and this is the unavaidable impurity

12:53 hyPiRion: Sgeo: Well, I don't think promises are mutable - I believe that's the same as saying vars are mutable because they can be unbound or not.,

12:54 ticking: Sgeo, --pedantic : so when you say you want the mechanism to be pure, I'd argue you can't because your entire assumption is based around listen changing state somewhere. Which is already polluting the pureness. :}

12:54 hyPiRion: Any pure program with promises will give the same result.

12:55 Sgeo: Hmm. I guess the promise itself might be immutable, but any useful operation on promises are impure.

12:57 hyPiRion: If you look at the functions as atomic elements, then that's true. But if you consider the whole program, then they can be considered pure.

12:57 ticking: hyPiRion, even a c program is pure if you only look at the whole program and unix pipes ;)

12:58 hyPiRion: ,(let [p (promise)] (pvalues (deliver :a) (deliver :b))) ; may bind p to either :a or :b, but the whole thing will, without doubt, fail regardless of what p got bound to at first

12:58 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

12:59 casion: C programs can be impure on their own in many, many ways :P

12:59 hyPiRion: ticking: Meh, I don't have the language to discuss this properly - to the CTMCP I go.

13:01 ticking: hyPiRion, lol :} I always find it to be easiest to define purity as stuff you can find a pretty straightforward transformationdo to lambda calc to

13:03 hyPiRion: meh, I consider it as same input in, same output out.

13:03 And no side effects.

13:04 ticking: yeah, that is one of the essential properties of it, but to properly transform it you have to apply that rule recursively

13:04 Sgeo: Is there any mnenmonic for remembering that condp's predicate's first argument is the one that's listed with the result and the second one is the one that's provided after the predicate?

13:04 ticking: so in a sense its a stronger criteria

13:05 Sgeo: I mean, it's a bit similar to Ruby's (except Ruby fixes the predicate to ===), but other than that?

13:12 dnolen: hyPiRion: ticking: I'm no expert, but it seems like promises exist as IVars in Haskell (Control.Monad.Par), and they are done purely there. so purity is perhaps an implementation detail? the outcome is the same. correct by design parallel programming via dataflow.

13:13 ticking: dnolen, I wouldn't count on it being pure, if the package identifier contains "monad" ^^

13:14 dnolen: ticking: all the docs I've glanced say pure.

13:14 ticking: dnolen, wicked :D

13:16 hyPiRion: dnolen, ticking: Well, it's more or less a discussion on how pure "pure" is.

13:16 ticking: hyPiRion, totally ^^

13:17 hyPiRion: (+ 1 2) is impure, as you need computation power and memory to perform it.

13:17 clojurebot: 3

13:19 Sgeo: dnolen, unamb is pure (assuming certain conditions of its arguments), but has an impure implementation

13:19 Not sure what that points to in this discussion

13:19 ticking: hyPiRion, not if you state that the above is a lambda calc expression, ^^ as lambda calc is defined as pure, all subsets must be :D

13:20 Sgeo, academic muscle training, and fun ^^?

13:20 Sgeo: Has anyone written unamb for Clojure?

13:21 Someone should

13:22 No longer would (or (some-infinite-loop) true) have to block forever, it could short-circuit!

13:22 hyPiRion: ticking: I don't know. Isn't lambda calc proven to be equivalent to a turing machine? And if that's the case, then a turing machine is also pure.

13:23 Sgeo: Probably easier to use futures directly

13:23 Or maybe not

13:23 * Sgeo is uncertain

13:23 hyPiRion: Sgeo: For non-haskellers, what is unamb?

13:24 ticking: hyPiRion, run two tasks return result of what returns first

13:24 hyPiRion, dove tailing as when building a turing machine to recognize the union of two languages

13:25 Sgeo: You're supposed to make sure that the arguments are either the same or bottom (infinite loop or exception)

13:25 (As in, one could be 5 and the other an infinite loop, but if one is 5 and the other is 6 you're doing it wrong)

13:25 hyPiRion: Ah.

13:26 Sgeo: As long as it's used like that, it's pure, because it shouldn't matter which one it returns

13:26 ticking: hyPiRion, yeah the transition functions are pure, as the configuration is the only input to them, the only impure thing is the loop that feeds the next configuraiton to the transition funs until there is nothign left to execute. But lambda calc is pure to the bottom ^^

13:27 Sgeo, interesting concept

13:27 hyPiRion: ticking: This is going way over my head now, so I'll assume you're right.

13:27 ticking: hyPiRion, don't assume rightness because of complex terms^^

13:28 all I said was, that the transitions the automaton takes can be modeled as a funciton that takes the current state and the band as input and returns a new band and state

13:28 Sgeo: Let's pretend that or is a function that takes two arguments and does logical or on them, no short-circuiting

13:28 hyPiRion: I like appeals by authority.

13:28 Sgeo: (defn por [a b] (unamb (or a b) (or b a)))

13:28 ticking: lol^^

13:29 Sgeo, yeah that would be cool, go ahead and implement it I'll use it :D

13:29 Sgeo: por is now a short-circuiting function, that... wait

13:29 * Sgeo abruptly realizes that short-circuiting functions are not a thing in Clojure

13:30 ahihi2: I would just like to point out that there is nothing impure about monads

13:30 in response to < ticking> dnolen, I wouldn't count on it being pure, if the package identifier contains "monad" ^^

13:30 ticking: ahihi2, yeah the haskell guys cheated

13:30 Sgeo: unamb can't be a function in Clojure unless it takes functions

13:31 hyPiRion: Sgeo: You could sprinkle some futures and promises over a macro

13:31 ticking: Sgeo, yeah i'd have to be a macro

13:31 ahihi2: ticking: cheated?

13:32 Sgeo: I'm actually wondering if agents would make more sense, since I could... n/m

13:32 Yeah, futures and promises.

13:33 I derped because I failed to conceive of taking one promise and giving it to a bunch of futures

13:33 ticking: ahihi2, yes monads are officially pure functions, but as you can "simulate" side effects with it, you basically got them ^^

13:33 ahihi2: no... IO is impure, but that's true whether you make it a monad or not

13:34 more specifically, _execution_ of IO is impure

13:34 whereas evaluation is not

13:34 Sgeo: I'm going to throw together a macro and paste it somewhere whether or not it's tested

13:34 hyPiRion: Actually, I'd just go Thread. instead.

13:34 Sgeo: I still don't have a decent Clojure environment

13:35 hyPiRion, hmm, why?

13:35 hyPiRion: Let me try to implement it first ;)

13:36 ClusterCat: just a quick question, what is the current way of including native deps to lein? (for LWJGL) Do I really have to repack like described here: https://github.com/swannodette/native-deps/blob/master/readme.textile ?

13:37 ticking: ahihi2, like I said, to me they chated ;}

13:38 Sgeo, environemt as in Ide?

13:38 Sgeo: ticking, as in IDE and Clojure implementation

13:39 ticking: Sgeo, how many clojure implementations are there^^?

13:39 Sgeo, I really like emacs with the lively package

13:40 Sgeo, ah sorry emacs-live https://github.com/overtone/emacs-live

13:45 hyPiRion: Sgeo: https://www.refheap.com/paste/4638

13:46 Sgeo: hyPiRion, erm, I ended up trying to write it to have any number of arguments

13:47 hyPiRion: Heh, it shouldn't be that difficult

13:48 Sgeo: https://www.refheap.com/paste/4639

13:48 I should probably really set up a Clojure environment to test that

13:48 I didn't use delivered?

13:50 hyPiRion: ,(let [p (promise)] (deliver p 1) (deliver p 1))

13:50 clojurebot: nil

13:50 hyPiRion: Hm.

13:50 Sgeo: ,(let [p (promise)] (deliver p 1) (deliver p 1) @p)

13:50 clojurebot: 1

13:51 Sgeo: ,(let [p (promise)] (deliver p 1) (deliver p 2) @p)

13:51 clojurebot: 1

13:51 hyPiRion: That's scary.

13:51 naeg: not all lisp dialects use that much lazy seqs as clojure does, right?

13:51 hyPiRion: naeg: True.

13:52 naeg: thanks hyPiRion

13:52 Sgeo: ...I accidentally called it umamb

13:54 It really should have a way to kill the other threads, hmm

13:54 hyPiRion: Sgeo: Yeah, I know

13:56 .interrupt, isn't it?

13:56 Sgeo: I don't know Java.

13:58 Maybe we should be writing a function and then just laying a macro on top of it

13:58 Frozenlock: I just discovered that I can do `(map :key map)' instead of `(map #(:key %) map). I'm a little ashamed.

13:59 Chousuke: heh :P

13:59 in general, whenever you do #(foo %) it's replaceable with just foo, unless foo is a macro or a java method

14:00 Sgeo: And #(foo bar %) is replaceable with (partial foo bar)

14:00 Well, actually, (partial foo bar) is more general

14:00 Chousuke: I tend not to use partial

14:00 I'd just use the anonymous function

14:00 hyPiRion: It's a bit slower though, which is kind of sad.

14:00 Frozenlock: I've never used partial...

14:01 Chousuke: and re threads, interrupt doesn't actually do anything useful unless the thread is actively checking whether it has been interrupted.

14:01 or if it's blocking, in which case an exception is thrown in the thread

14:01 IIRC

14:02 Sgeo: Could use futures...

14:03 Chousuke: well futures use java threads so the semantics don't really change

14:04 michaelr525: hello

14:04 Sgeo: Chousuke, but could use future-cancel rather than hoping that .interrupt does something

14:07 * Sgeo is pondering if it would make sense to make a lazy sequence of threads and pass that sequence in to each thread?

14:08 Sgeo: Or I could just fork another thread that waits on the promise and when the promise is fulfilled kills all the futures

14:12 jaley: can anyone help with a design question? I want to know when it's appropriate to start this flow chart: https://github.com/cemerick/clojure-type-selection-flowchart

14:12 i.e., how do I know I need a type?

14:19 michaelr525: hmm

14:20 how can i add multiple compojure routes to the handler?

14:20 I mean, i have a function which generates a list of routes which I want to add to (defroutes handler ...)

14:23 Sgeo: https://www.refheap.com/paste/4640

14:23 More stuff I should test if I ever get around to it

14:24 Ouch, hmm

14:25 https://www.refheap.com/paste/4641

14:25 Closer to correct, because I need to call fun, not deliver fun.

14:26 *sigh*

14:26 I need to get an environment where I can test this before doing anything else, I think I see another problem

14:41 You know what, I have Clooj. I'll try it in Clooj.

14:47 And Clooj isn't working nicely. Why should it?

14:50 Seems to be working!

14:50 (unamb (+ 2 2) (* 2 2))

14:50 4

14:53 ticking, try https://www.refheap.com/paste/4641

14:53 Wait, no, don't

14:53 https://www.refheap.com/paste/4643 there we go

14:53 naeg: would really appreciate if some of you would give me feedback on my newest blog post about Conway's Game of Life in Clojure: http://programmablelife.blogspot.co.at/2012/08/conways-game-of-life-in-clojure.html

14:54 it is actually not meant to be read by Clojure programmers btw

14:55 casion: seems strange that I have to click a link to see the full clojure source, but not the python

14:55 naeg: casion: oh, I'll add that one too. thanks

14:56 * Sgeo pokes other people towards his unamb code

14:59 naeg: casion: or did you mean why I explain the clojure code in such great detail and the python not at all?

15:00 uvtc: naeg: just my opinion regarding style, but I don't like how the code samples appear to have some lines with dark or light background (presumably because you're referring to those lines in the text below them).

15:00 casion: naeg: I mean that the full python source is there in plain sight, but one has to click a link to see the clojure source

15:00 and the light-dark thing I dislike as well

15:00 uvtc: (naeg: more on the style: I don't think single-line code snippets need line numbers enabled)

15:00 casion: the writing seems clear though

15:01 naeg: uvtc: yes, I tried out that highlight feature of SyntaxHighlighter. If more people tell me this, I'll remove it

15:02 ok, already 4 people complaining about line highlighting - will remove that for sure. and good point uvtc about line numbers

15:03 uvtc: naeg: Though I realize you're probably more interested in more substantive comments on your Clojure code. :)

15:03 naeg: casion: I'm unsure about adding the whole Clojure code inside the blog post, it seems quite long to me already

15:03 uvtc: I already had a few people in #clojure taking a look at it, but I'm still open for suggestions (especially for create-world)

15:04 casion: naeg: It looks like it's the same LOC as the python example

15:04 at the very least, if you're trying to show people clojure, show the whole clojure code.. and link to the python example

15:04 that's my thought at least :)

15:05 naeg: casion: I thought it would be a better idea to show them the code function for function instead of throwing everything at them at once

15:05 casion: naeg: you can't do both?

15:05 uvtc: naeg: I'd also like to see the complete Clojure program. In one big block, it's easy enough to scroll past. :)

15:05 casion: most programming language blog posts and books and tutorials work function by function, then end with the whole thing

15:06 naeg: convinced, makes sense. will add it

15:09 and explanations are understandable to you? of course you have to assume you would have no clue about clojure

15:10 casion: seems ok to me, but I'm no expert by far :)

15:15 hughfdjackson: in defrecord, what's the rational behind passing a vector of symbols

15:15 rather than one of keywords

15:15 given that the resultant map uses keywords?

15:17 naeg: thanks for your feedback casion and uvtc

15:31 freiksenet: why are clojure data structures called persistent and not functional?

15:31 hughfdjackson: freiksenet: from wiki: "In computing, a persistent data structure is a data structure that always preserves the previous version of itself when it is modified"

15:31 freiksenet: wouldn't 'functional' be a more correct name?

15:31 yesyes

15:31 also there are non-functional persistent data structures

15:31 hughfdjackson: i assume that's cause that's what they do n.n correct me if i'm wrong

15:32 freiksenet: persistent is a bigger set than functional

15:32 technomancy: freiksenet: "functional" is a property of programs, not data structures.

15:32 freiksenet: technomancy: again, that's wrong.

15:32 technomancy: freiksenet: OK, that's an interesting opinion.

15:32 freiksenet: see landmark book 'pure functional data structures'

15:32 by Okasaki

15:33 hughfdjackson: freiksenet: i wonder if it's simply because the use of 'persistent data structure' causes less debate ;)

15:33 technomancy: I suspect the publishers wouldn't have been to keen if he insisted on titling it "Data structures useful for writing purely functional programs."

15:33 *too

15:33 gfredericks: does 'pure functional' in that context refer to the implementation?

15:33 freiksenet: technomancy: "Purely functional is a term in computing used to describe algorithms, data structures or programming languages"

15:34 gfredericks: because in that case I don't think clojure's data structures are functional

15:34 technomancy: anyway, "persistent" has a very clear, specific definition, while "functional" is vague and means different things to different people.

15:36 freiksenet: gfredericks: depending on how deep you go no data structures are functional :)

15:36 gfredericks: but that's a valid point

15:36 gfredericks: freiksenet: sure, but if implementation is all we're talking about then there's no reason to call clojure's data structures functional; it could only be misleading

15:36 implementation at any level

15:36 casion: calling a data sturcture functional seems odd, since data by definition is not a function

15:37 gfredericks: casion: that's an ironic thing to say since some of clojure's data structures are functions :D

15:37 technomancy: well, maps are functions, as are vectors

15:37 lists aren't functions but are persistent

15:37 anyway, it's not a very clear term.

15:38 freiksenet: both are not, IMO

15:38 gfredericks: what else might persistent mean?

15:40 freiksenet: hm.

15:40 technomancy: gfredericks: I guess you are right

15:40 thanks

15:44 casion: gfredericks: it was my understanding that data structures in clojure are classes that encapsulate the data, and an invoke method

15:45 it's just presented syntactically as the same thing

15:45 is that incorrect?

15:46 gfredericks: casion: I can't figure out what you mean precisely enough to say one way or the other

15:46 what two things are you saying are being presented as the same thing?

15:46 casion: say a key in a map

15:47 the key is both data and a function (being invoke)

15:47 gfredericks: yes the fact that these different things are functions is orthogonal to their dataness; and probably not related to the previous discussion

15:48 but in the implementation it's one class doing both things

15:48 that'd be easier to break apart if they were implemented with types and protocols

15:50 casion: ok, thanks for the clarification

15:56 augustl: is there a way to have lein-ring call a function to get my handler? I don't have a default handler for my app, I need to call a function with {} as arguments to get an actual handler

15:57 gfredericks: a handler is a function; so you can give lein-ring a function that does whatever complicated thing you want it to do

15:58 including making new handlers and deferring to them

16:00 augustl: gfredericks: I probably need to make a "memoize" type function, then, that creates and returns a handler on the first call, and returns the one it created on subsequent calls

16:00 gfredericks: augustl: delay is a silghtly simpler mechanism for that kind of thing

16:01 augustl: nice, looking it up

16:02 very useful. I seem to learn a new function every day :)

16:03 hmm, delay doesn't seem to return a function, it returns a ref, right?

16:04 ..ish. Getting "java.lang.ClassCastException: clojure.lang.Delay cannot be cast to clojure.lang.IFn"

16:04 gfredericks: a reference that you want to call deref on

16:06 augustl: seems like lein-ring doesn't support it

16:06 a defer in my project.clj also causes an error

16:07 deref*

16:07 gfredericks: lein-ring doesn't have to support it

16:07 (let [my-real-handler (delay (make-handler {}))] (defn my-lein-ring-handler [req] (@my-real-handler req)))

16:08 augustl: ah

16:27 muhoo: why the delay?

16:28 gfredericks: sounded like he didn't want it created unless necessary; maybe it does some IO so he doesn't want to create it at compile-time

16:28 muhoo: thanks

16:53 bosie: whats the way to test multi threaded apps in clojure?

16:54 gfredericks: what aspect do you want to test?

16:54 bosie: gfredericks: whether or not i have multi threaded related bugs ;)

16:54 gfredericks: how do you tell it is working correctly?

16:55 bosie: gfredericks: so i don't override data, don't have race-conditions etc

16:56 gfredericks: that sounds about as elusive as "I want to make sure there aren't bugs"

16:56 bosie: gfredericks: well

16:56 gfredericks: there are general strategies for avoiding those kinds of things, like using immutable data and pure functions

16:56 and doing the multithreading at a high level if you can

16:57 but if you want to test it, you have to at least have something positive that you're looking for

16:57 bosie: gfredericks: more wondering how i would even introduce the problems? how would you set it up

16:57 gfredericks: run a bunch of threads at the same time doing a bunch of stuff?

16:57 chouser: tests can't prove the absence of bugs, and writing tests that specifically cause certain orderings between threads is very tricky and rarely worth it.

16:58 bosie: hm

16:59 chouser: if you have a race condition that causes problems in the wild, it is possible to use thread synchronization mechanisms (futures, countdown latches, semaphores, etc.) to specifically reproduce it in a test.

17:00 I have done this, in fact gone so far as to create a set of tools for writing such tests. I highly recommend avoiding this approach.

17:00 bosie: gfredericks: how would that do anything? if you can't guarantue that the setup you have in the test actually would cause a e.g. overiding data, then running threads and hoping for the best doesn't prove anything

17:00 chouser: so what approach do you recommend?

17:01 chouser: bosie: pure functions on immutable values, so that there's no state changes that can be racing. :-)

17:01 gfredericks: bosie: it would give you a minor amount of confidence, which I think is all you can ask for from a testing approach without getting into what chouser is talking about

17:01 bosie: chouser: how would you handle non-pure functions?

17:01 chouser: like reading to/from a file?

17:02 cshell: You're using multiple threads to write to the same file?

17:02 bosie: cshell: ideally, guess not ;)

17:02 chouser: bosie: well, what we've done is to concentrate the non-pure stuff into as small an area as possible, so that as much code as possible is pure.

17:02 cshell: why not just have one thread responsible for the read/write?

17:03 chouser: this often means moving the impure stuff to the outside, calling in to pure functions (since the other way around ends up with everything being impure).

17:03 bosie: chouser: right

17:04 chouser: so basically the 'helper' functions are pure. the rest is impure

17:04 cshell: can't keep everything in memory

17:05 hm

17:05 ok

17:05 chouser: which also means you don't use datastructures which are implemented in java, right?

17:06 chouser: bosie: right

17:06 bosie: chouser: unless they are explicitely thread-safe

17:06 chouser: well, not the impure ones. there are a few java libs that implement immutable data types

17:06 Joda time, Google collections, etc.

17:06 cshell: Google Guava's collections, right?

17:06 chouser: yeah

17:08 bosie: you can sometimes use lazy seqs if for data that won't fit in memory

17:09 And of course this doesn't prove your code is correct, but the less often you have to think about multiple threads touching a mutable thing, the less likely you are to make mistakes of that sort.

17:09 bosie: chouser: thats for sure. that is what intrigues me about good ol' clojure

17:11 chouser: more concretely, I've been hesitant in the past to write functions that return multiple values (via a vector or something) to represent side-effecty actions to be taken, but having recently converted a subsystem to a style that does exactly that, I think it was clearly a win.

17:11 * gfredericks could say very similar things

17:12 gfredericks: (-> (read-input) (figure-out-what-to-do) (do-it))

17:12 where all the business logic is in the middle

17:13 in our case that meant parallelizing the middle piece was easy and not scary

17:18 emezeske: There are strategies you can use to help surface bad threading behavior

17:19 E.g. set up load tests that put your server (or whatever) under load, preferably stressing it similarly to how it will be stressed in production

17:19 No guarantee that will find bugs, but it does boost confidence that things aren't horribly broken

17:26 bosie: emezeske: fakely boosting it ;)

17:34 uvtc: Is there a game lib for use with Clojure, something like SDL? Or do most folks start off with just using Swing?

17:41 nz-: uvtc: look at game libs for Java

17:42 uvtc: there you'll find OpenGL and SDL like stuff

17:44 technomancy: uvtc: just penumbra, which is unmaintained.

17:44 uvtc: Hm.

17:44 technomancy: you can use quil, but it's not really on the same level in terms of performance

17:44 bosie: chouser: just came to the careers page at lonocloud. how do you do pair programming remotely?

17:45 uvtc: Just looking for simple not-high-performance 2D-graphics with some sounds.

17:45 chouser: bosie: we use a custom convenience layer on top of tmux and excellent polycom speakerphones

17:45 technomancy: uvtc: ah, quil should fit the bill then

17:46 bosie: chouser: tmux, so you are using vim/emacs?

17:46 technomancy: it's pretty pleasant to work with

17:46 chouser: bosie: yes. emacs + evil

17:46 bosie: ok

17:46 technomancy: chouser: is your entire team switched over?

17:47 bosie: chouser: how do you handle different emacs configs? when i pair with another vim programmer, he can't use my config and vice versa…. slows us down a wee bit

17:47 chouser: technomancy: yep. some people stay out of the vim-bindings mode, but nobody yet has complained about having it available for the sake of easily allowing vimmers to control things when pairing.

17:47 technomancy: chouser: ah, so you swap it on or off depending on who's driving

17:48 bosie: ok

17:48 chouser: technomancy: yeah, C-z toggles off vim bindings when evil is loaded

17:48 technomancy: seems like you pretty much have to agree on some level of standardization

17:49 chouser: bosie: so far nobody has insisted on bringing a lot of custom emacs config. We have a common config that everyone seems content with plus of course the occasional personalization

17:49 bosie: chouser: weird

17:49 chouser: but congrats on getting all of them on emacs

17:49 chouser: we started with technomancy's starter kit and went from there.

17:49 technomancy: the amount of cursing that happens when someone else comes across a binding that doesn't do what they expects tends to serve as a good enforcement mechanism

17:50 chouser: we're mostly not old emacsers. In fact, almost everyone used vim until learning Clojure, if not later.

17:50 bosie: chouser: hah. i am in the same boat. waiting to pick up emacs until i know clojure will stick with me ;)

17:51 chouser: but at work we have unfortunately a wide range of editors/ides. can't seem to agree on the one thing

17:51 chouser: bosie: yeah, emacs isn't the panacea that I was hoping for. But with evil in there it's been a much smoother transition.

17:52 technomancy: you definitely have to make some hard choices to make remote pairing work

17:52 bosie: chouser: just out of curiosity. how does evil manage keybindings?

17:52 technomancy: in most cases the access to a wider talent pool is well-worth it if you can get buy-in

17:52 chouser: of course now my fingers know a combination of keystrokes that makes me useless in both stock emacs *and* stock vim. :-/

17:52 bosie: not sure what you mean.

17:52 bosie: chouser: sure, it can introduce the functionality of vim/modal mode etc. but the keybindings esp. of some of the third party plugins like latex are ridicilous. does evil automatically rebind them?

17:53 C-c C-f C-b => insert bold face text

17:54 chouser: ah, yes, some special modes work less well than others, but the amount of overlap between valid emacs and valid vim bindings is surprisingly small. So in vim normal mode, and especially in vim insert mode, most emacs bindings still work fine.

17:55 this allows us to use paredit comfortably.

17:55 bosie: chouser: which is the point… i really don't wanna use emacs bindings ;)

17:55 chouser: i much rather press ,fb or sth

17:55 chouser: our biggest pairing problems are actually around term colors, not key bindings.

17:56 bosie: k

17:56 technomancy: chouser: people using terminal.app garbage?

17:57 chouser: oh, it's really hard to place blame. xterm256 vs xterm, dark backgrounds vs. light backgrounds, different emacs themes, etc.

17:57 but sure, gnome term vs. terminal.app probably as well

17:57 Raynes: Emacs with evil-mode is pretty much the bee's knees.

17:57 * technomancy has no problem blaming people who use 8-color terminals =)

17:57 Raynes: All of the things I liked about Vim and all of the things I like about Emacs.

17:58 technomancy: light vs dark backgrounds is a pain though

17:58 everyone just needs to standardize on glasstty and we can move on =)

17:58 bosie: Raynes: do you ever need to use alt/ctrl like you do in vanilla emacs?

17:58 technomancy: clojurebot: glasstty?

17:58 clojurebot: No entiendo

17:58 uvtc: technomancy: thanks for the tip. Will have a look at quil.

17:58 technomancy: clojurebot: glasstty is a great font for serious hacking: http://sensi.org/~svo/glasstty/

17:58 clojurebot: You don't have to tell me twice.

17:59 technomancy: clojurebot: you say that, but sometimes I do.

17:59 clojurebot: It's greek to me.

17:59 Raynes: bosie: Yes. You don't use evil-mode to replace everything in Emacs. You use it to add things from Vim.

17:59 technomancy: case closed

17:59 bosie: Raynes: using emacs with regular keybindings gives me cramps in my hands, so yes, i would add evil to get rid of the keybindings

18:00 Raynes: I've never had those problems.

18:00 My ctrl key is my capslock key and it is not even physically possible for me to get a cramp.

18:01 bosie: Raynes: cramp, carpal tunnel syndrome,.. not sure. but it isn't a nice feeling either way

18:01 Raynes: esc is my capslock ;)

18:01 Raynes: If you've got your keyboard set up for Vim, chances are Emacs isn't going to work optimally for you.

18:02 tos9: What's there to set up

18:02 Raynes: Switch capslock and ctrl.

18:02 bosie: Raynes: nah, i started with emacs years ago and after 3 weeks i gave up because i couldn't get rid of the problems. switched to vim

18:02 Raynes: vim never ever gave me those problems

18:02 tos9: Raynes: Yeah. I have that for Vim. It works fine for Emacs too.

18:02 Raynes: bosie: So far you've listed one problem.

18:03 bosie: Raynes: kinda major....

18:03 Raynes: One which I proposed a possible solution to, that you implied you never tried.

18:03 bosie: Raynes: switching capslock?

18:03 Raynes: i have a kinesis keyboard, ctrl is on my homerow

18:03 Raynes: *shrug*

18:03 bosie: Raynes: so is alt

18:04 Raynes: Then I simply don't understand. But hey, I don't have to. You're happy with Vim. :)

18:04 bosie: Raynes: i am not ;)

18:04 technomancy: you get to ignore potential name conflicts if they don't have any github forks and are hosted on a separate runtime, right?

18:04 them's the rules

18:05 cshell: What are the names of those new keyboards which have the keys directly in line with each other? like c3900 or something?

18:05 technomancy: type matrix is the only one I know of

18:05 cshell: yeah, that's the one the 2030

18:05 thanks technomancy

18:06 Has anyone here used one of those?

18:06 bosie: cshell: give this one a chance, it is awesome http://www.kinesis-ergo.com/advantage.htm

18:07 cshell: thatnnks, but I've never liked those curvy keyboards

18:07 er, thanks

18:07 :)

18:07 bosie: k

18:07 cshell: the typematrix one looks interesting because of the key placement

18:08 but I never have pain from typing so maybe I don't need one

18:08 of either

18:08 uvtc: I missed most of this conversation, but love the kinesis advantage (formerly "contoured") keyboard.

18:08 qmx: bosie: these keyboards are scary - I'd rather get an oldy "clicky" IBM

18:08 bosie: uvtc: yup!

18:09 qmx: hehe yea well… just be assured, they aren't what most companies sell as ergonomic (e.g. microsoft, logitech … ) ;)

18:09 qmx: bosie: no, I'm talking about the oldies :)

18:10 casion: I use a filco majestouch

18:10 much prefer it over the model m

18:10 key laout is colemak, no need for crazy ergo keyboards

18:10 bosie: gtg cu

18:11 uvtc: Since casion brings up colemak, anyone using one of these keyboard layouts http://mkweb.bcgsc.ca/carpalx/?full_optimization ?

18:12 casion: I do

18:12 I use a modified colemak

18:12 easier to just call it colemmak :)

18:12 uvtc: I'm using dvorak, but was thinking of trying out QFMLWY .

18:12 cshell: what's the difference betwen dvorak and qfmlwy?

18:13 casion: less finger travel

18:13 more home row usage

18:13 uvtc: QFMLWY is original --- not based on an existing layout.

18:13 cshell: for dovrak?

18:13 uvtc: There's a plot somewhere on that site ... lessee..

18:13 casion: uvtc: I use the modified colemak from the carpalx website

18:13 it's on there somewhere

18:14 cshell: how do you guys handel typing on other computers, ones which have standard qwerty?

18:14 casion: you just type?

18:14 i can type normally on colemak, qwerty, dvorak and modified colemak just fine

18:14 cshell: right, but context switching must cause some challenges, right?

18:15 casion: nope

18:15 uvtc: cshell: My fingers have long-forgotten qwerty. I hunt-and-peck until I can remap the keys.

18:15 Ah, here's the plot I was looking for: http://mkweb.bcgsc.ca/carpalx/?popular_alternatives

18:16 nz-: what is the home row?

18:18 uvtc: nz-: depends on the layout. dvorak has aoeu and htns on the home row.

18:21 nz-: uvtc: so the basically the row in the middle

18:22 cshell: yeah, i think where your fingers are supposed to rest

18:23 uvtc: nz-: http://en.wikipedia.org/wiki/Homerow#Home_row

18:57 Apage43: keyboard talk happened D:

20:47 ibdknox: Hiring link posted to HN

20:47 here we go

20:47 lol

20:47 http://kodowa.com/jobs

20:48 Raynes: ibdknox: evenin' partner

20:49 ibdknox: Raynes: hola

20:49 casion: everyone has to be in california

20:50 and I just learned where soma is

20:51 Raynes: ibdknox: Excited to see what happens when you've got a team.

20:51 ibdknox: Raynes: you and me both

20:51 lol

20:57 brehaut: ibdknox, Raynes: productivity decresses as 2pm meetings take over from writing the codes

21:02 ibdknox: brehaut: :p

21:05 timvisher: is there an easy way to get `lein ring server` to get me a port that slime can connect to?

21:12 xeqi: for nrepl you could use https://github.com/cemerick/drawbridge, but not sure what you would do for slime

21:22 cshell: Is there anything in particular I should look for when my robert hooke hooks get called as expected when I call the hooked function from the REPL, but don't get executed when I call a function within code that calls the hooked function?

21:25 djanatyn: is there something like hackageDB for clojure?

21:26 clojars doesn't seem to have an interface for browsing through packages

21:26 qmx: any reason for clojars having so many -SNAPSHOT packages?

21:27 cshell: qmx: Continuous Integration builds?

21:27 djanatyn: which packages are you trying to browse?

21:28 qmx: cshell: I'm starting to play with clojure and there's a ton of packages advertised as "good to use" w/ snapshot versions - is the semantics different than in the maven world?

21:28 cshell: no, same semantics

21:29 qmx: so, discouraged for serious use

21:29 "serious"

21:29 djanatyn: cshell: all of them. I'm just interested in using clojure for something, so I was looking for a fun package

21:29 cshell: what packages are you talkin gabout?

21:29 qmx: djanatyn: clojure-toolbox.com has some good tips

21:30 cshell: er, qmx: what packages are you talking about?

21:30 djanatyn: normally you can just browse the source

21:30 qmx: cshell: several, in one week I bumped in at least 10 that say on their readmes: [foo.bar X.XX-SNAPSHOT]

21:31 cshell: djanatyn: the clojure core has documentation you can browse

21:31 qmx: that's why I'm asking

21:31 djanatyn: cshell: I mean browsing a list of all packages on clojars

21:31 tomoj: djanatyn: well.. https://clojars.org/repo/ :)

21:31 cshell: qmx: semantics are the same, I haven't seen a useful library on clojars that didn't have a release version

21:31 tomoj: also https://clojars.org/repo/all-jars.clj

21:31 qmx: cshell: ha! so we're on the same page :)

21:31 tomoj: as if that's helpful..

21:32 djanatyn: tomoj: thanks!

21:32 cshell: qmx: I don't like to use snapshots unless there's a critical bug fix in one that's impacting me

21:32 tomoj: djanatyn: also note `lein2 search` (which seems to only work inside a project)

21:33 cshell: qmx: and then you can shoot the author an email to release it, or you can release one yourself if it's on github

21:42 can someone please tell me the difference between passing the function x by its symbol and passing it with #'x

21:42 I know it has something to do with 'the value at call time versus the value pointed at by x' but I can't formalize it

21:44 tomoj: #'x is reader shorthand for (var x), which returns the var

21:44 (def x 3) and then #'x return the same thing

21:45 you can deref the var to get its value: @#'x

21:45 but vars also implement IFn by derefing and calling that

21:46 so (#'inc 3) works

21:46 more about vars: http://clojure.org/vars

21:46 cshell: Right, but if I put a closure over a function referenced by the symbol only, then try to hook it, it doesn't work

21:47 tomoj: by hook it do you mean redef it?

21:47 cshell: Using the Robert Hooke library, so that's what is happening right? It's redefining the var

21:47 when i add the hook

21:48 tomoj: hmm

21:48 (do (def foo (constantly 3)) (def bar #(foo)) (def foo (constantly 4)) (bar))

21:48 I get 4

21:48 cshell: but even if I load the hooks first, the closure seems get its own binding to the function

21:48 unless i pass in the var

21:49 tomoj: best chance would be to paste an example somewhere if you can

21:50 oh, maybe I see

21:51 cshell: it looks like the hook library is altering the root binding

21:53 tomoj: something like this? https://gist.github.com/d4783314ac651d0c06b3

21:54 (substitute redef for hooking)

21:54 cshell: yeah, i think that's very similar

21:54 tomoj: the reason that returns 3 is that (foo bar) passes the value of bar at that time to foo

21:54 the value of bar is a function

21:55 when you hook you don't change the function, you just point the var at the new hooked function

21:55 cshell: so the closure keeps the original value of the var?

21:55 but if you pass (foo #'bar) it will work right?

21:56 tomoj: right

21:56 passing the var in instead of the function would make sense in an example like that if you want to hook

21:56 cshell: yeah, that's what I'm hitting up against

21:56 I notice that, in cemerick's book, he uses #' when referencing function vars - is this more idiomatic?

21:58 tomoj: you mean in english text?

21:59 cshell: I mean, it's probably better to pass my vars (which contain functions) by passing the var itself, ie #'

21:59 tomoj: I would never write (map #'inc coll) for example, I only pass the var in the rare cases where it's going to change and I want the change

21:59 clojurebot: map is an evil genius.

22:00 cshell: So, if you do just (map inc coll) you can't hook the inc?

22:01 tomoj: right, unless it was hooked before (map inc coll) was evaluated

22:02 cshell: okay, that's a lot to think about - I appreciate your help, tomoj

22:03 thank you

22:04 tomoj: I don't think I fully understand all the details

22:04 &(do (def bar (constantly 3)) (defn foo [] (bar)) (def bar (constantly 4)) (foo))

22:04 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

22:04 tomoj: oright

22:07 I guess I understand that operationally, but I don't know how to explain it

22:08 cshell: yeah, me either - just that when I do it, the hook file has to load the code which instantiates the closure - then it creates the hook

22:08 amalloy: tomoj: (bar) always looks up the current value, because bar is known to be a var. but if you do something like (let [x bar] (fn [] (x))), changes to bar won't show

22:08 cshell: amalloy: and that's what happens with the closure, right? it sets a binding within that closure?

22:09 amalloy: i don't have enough context to answer that question

22:10 tomoj: amalloy: I see, thanks

22:10 in my gist, (foo bar) derefs #'bar immediately and foo just receives the value

22:11 so any changes to #'bar afterward don't matter

22:56 Sgeo: Hmm

22:56 I think unamb might be less useful in Clojure than in Haskell

22:57 It's hard to do variadic or with unamb directly

22:59 tomoj: do you mean amb?

23:00 I don't see why you'd want a variadic or in clojure with unamb-like semantics

23:01 Sgeo: tomoj, short-circuiting in all directions isn't interesting?

23:01 https://www.refheap.com/paste/4643

23:03 gfredericks: it's never been clear to me if future-cancel will interupt if the thing has started already

23:04 tomoj: the thing I associate with 'unamb' is exactly the same as the think I associate with 'amb' except that unamb has the requirement that the two values will be equivalent (for some definition of 'equivalent' taking into account bottom)

23:04 amalloy: gfredericks: usually. no guarantees

23:04 tomoj: oh I see you specify "give the same value"

23:05 gfredericks: amalloy: so it could conceivably run forever and never be interrupted?

23:05 amalloy: yes

23:06 eg, (loop [] (recur)) can't be interrupted, because there's no system call for the jvm to insert an InterruptedException into

23:06 gfredericks: I see.

23:06 lame jvm. I hope you're getting some huge performance boost out of this.

23:06 * gfredericks glares at the jvm

23:07 amalloy: correctness boost, if i understand correctly. Thread/stop has been around since 1.0, and was deprecated because it's terrible for system stability

23:10 Raynes: Sure wish they hadn't done that.

23:13 gfredericks: &(loop [] (recur))

23:14 lazybot: Execution Timed Out!

23:17 Sgeo: Hmm, how dangerous is my unamb considering the possibility of some threads never actually cancelling?

23:17 (Memory-wise, I mean)

23:24 I'm beginning to hate the JVM more and more

Logging service provided by n01se.net