#clojure logs

2012-08-26

00:11synfinat_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.
00:11casionClojure Programming or Programming Clojure
00:11synfinat_cool, i'll take a look at those
00:11casionif you're more used to ruby, I'd think clojure programming is probab ly better
00:12synfinat_perfect
00:12casionfor me, being used to C, I've found more benefit in programming clojure
00:12casionjust my opinion, they're both very good books
00:12synfinat_we'll i'm equally fulent in those first three, although seems clojure is closer to ruby
00:15gfredericksclojurebot: stuartsierra is authoritative enough
00:15clojurebotIk begrijp
01:09emezeske$findfn 1 1
01:09lazybot[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
01:09emezeske$findfn [1 1] [1 1]
01:09lazybot[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
01:09emezeske$findfn inc 1 5
01:09lazybot[]
01:09emezeske$findfn 1 inc 5
01:09lazybot[]
01:09emezeske$findfn [inc 1 5] 5
01:09lazybot[clojure.core/last clojure.core/peek]
01:12emezeskeIs there a clojure.core function that, given a function and a number, composes that function recursively that many times?
01:12emezeskeE.g. (whatever inc 3) -> (inc (inc (inc %)))
01:15emezeskeActually, 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
01:16metellussomething with iterate, probably
01:18emezeskeYeah, (nth (iterate inc 5) 3) does the trick. That's the most concise I've come up with
01:21pandeiroemezeske: repeatedly doesn't do it?
01:22emezeskepandeiro: No, I want the initial arg to be threaded through, so the result of the first function is fed to the second, etc
01:24pandeiroemezeske: yah nvm, i was confusing with iterate anyway
01:25emezeskeI think maybe it's not a common thing to want to do
01:25amalloyemezeske: it's common enough, and iterate is the right answer
01:26amalloyif it galls you for some reason, you can do something silly like ##((apply comp (repeat 5 inc)) 1)
01:26lazybot⇒ 6
01:27emezeskeHeh, no gall for me. I just wanted to make sure I wasn't missing a better way to do it.
01:27emezeskeI just had that inkling that maaaaybe c.c had composed that already :)
01:32technomancy(apply comp (repeat inc 5)) is clearer imo
01:33technomancymaybe it's just me
01:34amalloysome of that's because of the awful argument order for nth
01:34amalloylike (->> 1 (iterate inc) (nth 5)) would be pretty nice
01:53SgeoHow often does jimduey come here?
01:56grisu
01:57emezeskeSgeo: Is that his irc nick?
01:57SgeoYes, apparently.
01:57SgeoAt least it was when he msg'd me a while ago
01:58emezeskeSgeo: 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
02:01amalloy$seen jimduey
02:01lazybotjimduey was last seen quitting 1 day and 6 hours ago.
02:39SgeoI hate protocols.
02:39SgeoSuppose I make a library with protocols, and allow users to extend stuff via the usual way to do that with protocols.
02:40SgeoThen I discover use cases which require multimethods. I switch my code over, but that breaks user code that's expecting a protocol-based system.
02:41RaynesYou hate protocols because you don't know when to use them vs multimethods?
02:42SgeoBecause 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)
02:43RaynesProtocols are like typeclasses.
02:47SgeoHaskell-style typeclasses, even with multiparamtypeclasses (which protocols are not like) are insufficient as far as I'm concerned
02:48amalloyso...don't use them
03:02magopianit seems it's not possible to use "apply" with "or", how would i go about that?
03:02amalloy&(doc some)
03:02lazybot⇒ "([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)"
03:02magopian(i'm mapping a function to a seq, which returns a seq of booleans, and i need to "or" them)
03:02magopianah :)
03:02magopiansure, thanks amalloy :D
03:03magopian(should have thought about that... :)
03:05Sgeo&(apply (partial some identity) '(true true false))
03:05lazybotclojure.lang.ArityException: Wrong number of args (4) passed to: core$some
03:06Sgeo&((partial some identity) '(true true false))
03:06lazybot⇒ true
03:06SgeoI'm ... not entirely sure what I was thinking
03:07SgeoOh, that some took a variadic amount of arguments as though it was or
03:12antares_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.
03:13Cr8I suppose I ought to dogfood that
03:24Cr8oh
03:24Cr8I can't spell.
03:27Cr8antares_: cool, got my project using the couchbase connection now :)
04:09magopianstack overflows happen when there's non tail recursive calls, is that right?
04:10magopiani 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 :/
04:10magopianthe problem: http://www.4clojure.com/problem/89
04:11magopianmy solution: https://friendpaste.com/7QiF9pQ1oe3J5KgTEKwDII
04:12SgeoDo note that Clojure isn't inherently tail-recursive, although there are ways around that
04:24Cr8magopian: the stack will overflow even if your recursive calls are in tail position
04:24Cr8you have to explicilty use (recur) to avoid stack blowup
04:25magopianoh really? didn't know that
04:25magopiannice to know ;)
04:25magopiani can't see a way to use recurse with my actual solution, will have to think about something new :/
04:26Cr8(recur) is basically: switch in these values and GOTO the last recur point
04:26Cr8which is either the top of the fn or the nearest loop
04:26SgeoCr8, too bad it can't also be used to effectively GOTO a different function
04:27Cr8that's the reason for recur
04:27Cr8if you could jump to another function that way then you could just do actual tail call elimination
04:28michaelr`good morning
04:29Cr8magopian: perhaps you can wrap it up with trampoline
04:29Cr8http://clojuredocs.org/clojure_core/clojure.core/trampoline
04:41magopianCr8: i doubt it, but i'll try ;)
04:43RaynesSgeo: That's what trampoline is for.
06:01Cr8aw, can't use future on 4clojure =P
06:31SgeoCr8, o.O why not?
06:31Cr8i don't knwow
06:32Cr8doesn't matter, my solution was wrong anyway
06:32SgeoTryClj doesn't like it either
06:32Sgeojava.lang.SecurityException: You tripped the alarm! future-call is bad!
06:32SgeoClojure>
06:33SgeoI think if I made a ClojureNomic, I might want to make my own sandbox
06:33SgeoBut, I'm fairly convinced that newLisp is a better language for a nomic than Clojure
06:33SgeoAnd it's now starting to sink in that "better for a codenomic" != "better general purpose language"
06:34RaynesCr8: 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.
06:34SgeoI assume you could build your own futures based on promises + Thread. and start.
06:35Sgeoerm, .start
06:36Cr8I would expect that Thread. would also be a no-no
06:36SgeoCr8, works for me in TryClk
06:36Sgeoerm, TryClj
06:37Cr8hm. Does it keep track of the threads you start and forcibly stop them?
06:38SgeoNo idea
06:40SgeoCrud, I don't think TryClj likes macros.
06:40RaynesCr8: Yes.
06:40SgeoNo biggie, my-future can take a function of 0 arguments instead.
06:40Cr8neat
06:42Cr8I guess that's why agents are also bad
06:42Cr8since they use a threadpool that the sandbox doesn't manage
06:42Sgeo(defn my-future [f] (let [p (promise)] (.start (Thread. #(deliver p (f)))) p))
06:43SgeoNote that my-future is a function that takes in a function, rather than being a simple macro
06:43SgeoSo (my-future #(+ 1 1)) instead of (future (+ 1 1))
06:55Cr8whee, got it
06:56RaynesI doubt it.
06:57RaynesYou can't define macros on 4clojure, and he said his solution was fundamentally incorrect anyways.
06:58Sgeomy-future isn't a macro (specifically for that reason), but yeah, fundamentally incorrect means I'm probably not helpful
07:01RaynesOh, right.
07:01RaynesI didn't mean to imply you were being unhelpful.
07:03SgeoI should make a macro that writes macros that merely deposit their body into an anonymous function and call some other function with that function
07:03SgeoAlthough I tried to write a macro-writing macro in CL once, it didn't work out too well
07:04SgeoAlso, I'd need to consider the role of arguments
07:09SgeoI still need to try to set up a sane Clojure environment on my comp
08:32jmlhow 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.
08:33tomswI get a ClassNotFoundException for com.sun.jdi.VirtualMachine whenever I try running lein ritz
08:33tomswdoes anyone know how to fix this with lein2?
08:42tomswah, realised that JAVA_HOME was pointing at the Oracle jdk but that /usr/bin/java was still pointing at the OpenJDK one.
08:58hyPiRionMan, common lisp's format (cl-format) is like a language in itself.
08:58hyPiRion,(require 'clojure.pprint)
08:58clojurebotnil
09:01hyPiRion,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 2 "cow" 3 "pig")
09:01clojurebot"Two cows and three pigs."
09:01hyPiRion,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 0 "cow" 3 "pig")
09:01clojurebot""
09:01hyPiRion,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 2 "cow" 0 "pig")
09:01clojurebot"Two cows"
09:01Bronsawtf
09:02SgeoOh cool, Clojure has a cl-format thing
09:02hyPiRion,(clojure.pprint/cl-format nil "~[~:;~:(~:*~r~) ~A~:*~:p~]~0@*~[~:;~*~[~:; and ~]~]~2@*~[~:;~0@*~[~*~:(~r~) ~A~:*~:p~:;~*~r ~A~:*~:p~]~]~0@*~[~:;~*~[~:;.~]~]" 2 "cow" 1 "pig")
09:02clojurebot"Two cows and one pig."
09:02SgeoThat's one less thing from CL I'll miss
09:02hyPiRionSgeo: I was so happy when I found it.
09:03SgeoThings I'll still miss: No JVM, CLOS possibly (not sure), condition system absolutely.
09:04SgeoNot setf as such, but it would be nice to have a functional equivalent... instead of mutating something it could give a modified copy
09:06hyPiRionSgeo: I believe multimethods is more flexible than CLOS
09:06hyPiRionThough I don't know if the efficiency is as nice.
09:06SgeohyPiRion, I believe that they're fakable at least a little in CLOS
09:07hyPiRionYeah, probably.
09:07hyPiRionIt's completely doable, so.
09:08SgeoHave 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,
09:11SgeoAnyways, there's an easier way to write domonad
09:11SgeoAt least I believe so
09:12SgeoOh, I'd also need to handle :when and :let
09:21xeqimonad comprehension?
09:28SgeoI'm starting to see that it's fine as it is
09:29hyPiRionheh
09:31SgeoI'm not entirely sure why this person uses symbol macros and the like when, afaict, dynamically-scoped variables would work fine.
09:32gfredericksthis person?
09:33Sgeohttps://github.com/clojure/algo.monads/blob/master/src/main/clojure/clojure/algo/monads.clj
09:33SgeoKonrad Hinsen
11:02duck1123I'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:08duck1123looks like I can just do (map #(get-in % [:attrs :data-id]) elts) but is there a better way?
11:08Sgeo"algo.monads: Might work as-is! Trivial. Hey, when was the last time you saw 'trivial' and 'monads' in such proximity?"
11:08Sgeo^^a discussion of porting various libraries to ClojureCLR
11:09cshellduck1123: don't you just return the same thing that you select by?
11:09cshellor just identity?
11:11duck1123If I do (select doc [(attr? :data-id)]) it returns all the elements, not the attributes
11:14cshellhmm, yeah mapping over those is probably the way to do it
11:15cshellI thought there was another selector but i guess I was wrong
11:15duck1123I didn't really find anything prettier, probably because that's an easy enough op
12:00michaelr`hello
12:01_ulises'lo michaelr`
12:02michaelr`'sup
12:02_ulisesnot much, you?
12:03michaelr`i'm building something to scaffold admin interfaces
12:03_ulisesfor?
12:03clojurebotfor is not a loop
12:03_ulisesindeed not
12:03michaelr`for websites
12:03michaelr`web apps
12:03michaelr`you know, the crud stuff
12:04_ulisesmichaelr`: are you targeting noir by any chance?
12:04michaelr`well, compojure
12:04_ulisescool
12:04michaelr`i hope so
12:04michaelr`let's see in a few days :)
12:05_uliseslooking forward to it as I have a small project in the backburner and I dread writing the crud bits myself ;)
12:06michaelr`heh
12:19hyPiRionAlas, my attempt to get the computer project at my university to make a Clojure machine failed.
12:19nvy,(.set #'*ns* 0)
12:19clojurebot0
12:19nvy,(+ 1 1)
12:19clojurebot2
12:19nvynice
12:20Frozenlo`hyPiRion: A clojure machine? You mean directly hardware, no jvm?
12:20tickinghyPiRion, 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:21hyPiRionFrozenlock: yes, direct hardware.
12:23vedmwn
12:23hyPiRionticking: Kind of, but it's not running on "bare metal".
12:23hyPiRionCool that you get to build a lisp-machine though.
12:24tickinghyPiRion, 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:25tickinghyPiRion, semantically it is more of a erlang machine with s-expressions anyway ^^
12:25hyPiRionThat's really sweet.
12:28hyPiRionI know people actually built a LISP machine 4 years ago here. Feels like I missed the sweet spot to live by 4 years
12:28hyPiRion/s/to live/to be born
12:29tickinghyPiRion, 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:29tickinghyPiRion, do you mean the Igor?
12:29hyPiRionticking: yes
12:30tickinghyPiRion, 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:32hyPiRionticking: heh
12:33tickinghyPiRion, I'm more of a lisp guy, but have you seen the greenarray chips^^?
12:34hyPiRionticking: Nope
12:35tickinghyPiRion, http://www.greenarraychips.com/ pretty awesome stuff, they put 144 super tiny and reduced forth machines onto one chip
12:36hyPiRionwow, that's neat
12:36tickinghyPiRion, 100gops at 1 wat I think ^^
12:36tickinghyPiRion, I wish we had that for lisps ^^
12:37hyPiRionticking: I wish we had a lot for lisps.
12:39hyPiRionI 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:39tickinghyPiRion, yeah only approach that works ^^
12:41hyPiRionSgeo: Go on.
12:42SgeoGiving the result of a function (such as Seesaw's listen) to a function passed into that function
12:42SgeoI see how to do that via promises. But if there were a pure way to do that, that would be ... interesting
12:42gfredericksO_O
12:43gfredericksSgeo: can you describe that less abstractly?
12:43tickingSgeo, you mean a y-combinator^^?
12:43Sgeoticking, along those lines, I think.
12:43hyPiRionYeah, sounds like some combinator of some sort.
12:43Sgeo(listen) takes some arguments and a function, and installs the function as an event handler.
12:44tickingyou want to use the return value of listen in the event handler
12:44SgeoYes
12:44gfredericksI don't think you can do that purely
12:45gfredericksassuming you can't control how listen behaves
12:45tickingformal-proof time *yay*
12:45gfredericksalso assuming you consider promises to be impure :)
12:46SgeoI am
12:46hyPiRionpromises aren't impure :(
12:46tickingSgeo, the problem I think you have is the impurity of listen
12:46gfredericksyeah I qualified because that seems a bit ambiguous
12:46gfredericksyeah listen is for side effects
12:47SgeohyPiRion, a promise has a mutable state: Whether or not it's been delivered, and if delivered, what its value is.
12:47gfredericksI don't think promises are really less pure than lazy seqs
12:47gfredericksyou can implement a promise with a lazy seq I think :)
12:48tickingif 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:48gfrederickssort of; this is all really hairy :(
12:48SgeoHmm, I don't think Haskellers consider laziness to be impure, although the implementation is.
12:48tickingthe 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:49Sgeoticking, the return value can be of relevence without needing to have the entire thing computed.
12:49SgeoMaybe listen does something like conj'ing a 1 onto its return value, in a lazy structure.
12:50tickingSgeo, yeah lazyness makes it tricky, I was reasoning in lambda calc
12:50tickingbut 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:51tickingso you'd do something even worse than impurity, defining equality based on the stuff you have extracted so far from the lazy entity
12:52tickingthe only way this is of relevance is that the handler is somewhere stored to be called later, and this is the unavaidable impurity
12:53hyPiRionSgeo: 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:54tickingSgeo, --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:54hyPiRionAny pure program with promises will give the same result.
12:55SgeoHmm. I guess the promise itself might be immutable, but any useful operation on promises are impure.
12:57hyPiRionIf 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:57tickinghyPiRion, even a c program is pure if you only look at the whole program and unix pipes ;)
12:58hyPiRion,(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:58clojurebot#<SecurityException java.lang.SecurityException: no threads please>
12:59casionC programs can be impure on their own in many, many ways :P
12:59hyPiRionticking: Meh, I don't have the language to discuss this properly - to the CTMCP I go.
13:01tickinghyPiRion, 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:03hyPiRionmeh, I consider it as same input in, same output out.
13:03hyPiRionAnd no side effects.
13:04tickingyeah, that is one of the essential properties of it, but to properly transform it you have to apply that rule recursively
13:04SgeoIs 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:04tickingso in a sense its a stronger criteria
13:05SgeoI mean, it's a bit similar to Ruby's (except Ruby fixes the predicate to ===), but other than that?
13:12dnolenhyPiRion: 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:13tickingdnolen, I wouldn't count on it being pure, if the package identifier contains "monad" ^^
13:14dnolenticking: all the docs I've glanced say pure.
13:14tickingdnolen, wicked :D
13:16hyPiRiondnolen, ticking: Well, it's more or less a discussion on how pure "pure" is.
13:16tickinghyPiRion, totally ^^
13:17hyPiRion(+ 1 2) is impure, as you need computation power and memory to perform it.
13:17clojurebot3
13:19Sgeodnolen, unamb is pure (assuming certain conditions of its arguments), but has an impure implementation
13:19SgeoNot sure what that points to in this discussion
13:19tickinghyPiRion, 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:20tickingSgeo, academic muscle training, and fun ^^?
13:20SgeoHas anyone written unamb for Clojure?
13:21SgeoSomeone should
13:22SgeoNo longer would (or (some-infinite-loop) true) have to block forever, it could short-circuit!
13:22hyPiRionticking: 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:23SgeoProbably easier to use futures directly
13:23SgeoOr maybe not
13:23hyPiRionSgeo: For non-haskellers, what is unamb?
13:24tickinghyPiRion, run two tasks return result of what returns first
13:24tickinghyPiRion, dove tailing as when building a turing machine to recognize the union of two languages
13:25SgeoYou're supposed to make sure that the arguments are either the same or bottom (infinite loop or exception)
13:25Sgeo(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:25hyPiRionAh.
13:26SgeoAs long as it's used like that, it's pure, because it shouldn't matter which one it returns
13:26tickinghyPiRion, 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:27tickingSgeo, interesting concept
13:27hyPiRionticking: This is going way over my head now, so I'll assume you're right.
13:27tickinghyPiRion, don't assume rightness because of complex terms^^
13:28tickingall 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:28SgeoLet's pretend that or is a function that takes two arguments and does logical or on them, no short-circuiting
13:28hyPiRionI like appeals by authority.
13:28Sgeo(defn por [a b] (unamb (or a b) (or b a)))
13:28tickinglol^^
13:29tickingSgeo, yeah that would be cool, go ahead and implement it I'll use it :D
13:29Sgeopor is now a short-circuiting function, that... wait
13:30ahihi2I would just like to point out that there is nothing impure about monads
13:30ahihi2in response to < ticking> dnolen, I wouldn't count on it being pure, if the package identifier contains "monad" ^^
13:30tickingahihi2, yeah the haskell guys cheated
13:30Sgeounamb can't be a function in Clojure unless it takes functions
13:31hyPiRionSgeo: You could sprinkle some futures and promises over a macro
13:31tickingSgeo, yeah i'd have to be a macro
13:31ahihi2ticking: cheated?
13:32SgeoI'm actually wondering if agents would make more sense, since I could... n/m
13:32SgeoYeah, futures and promises.
13:33SgeoI derped because I failed to conceive of taking one promise and giving it to a bunch of futures
13:33tickingahihi2, yes monads are officially pure functions, but as you can "simulate" side effects with it, you basically got them ^^
13:33ahihi2no... IO is impure, but that's true whether you make it a monad or not
13:34ahihi2more specifically, _execution_ of IO is impure
13:34ahihi2whereas evaluation is not
13:34SgeoI'm going to throw together a macro and paste it somewhere whether or not it's tested
13:34hyPiRionActually, I'd just go Thread. instead.
13:34SgeoI still don't have a decent Clojure environment
13:35SgeohyPiRion, hmm, why?
13:35hyPiRionLet me try to implement it first ;)
13:36ClusterCatjust 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:37tickingahihi2, like I said, to me they chated ;}
13:38tickingSgeo, environemt as in Ide?
13:38Sgeoticking, as in IDE and Clojure implementation
13:39tickingSgeo, how many clojure implementations are there^^?
13:39tickingSgeo, I really like emacs with the lively package
13:40tickingSgeo, ah sorry emacs-live https://github.com/overtone/emacs-live
13:45hyPiRionSgeo: https://www.refheap.com/paste/4638
13:46SgeohyPiRion, erm, I ended up trying to write it to have any number of arguments
13:47hyPiRionHeh, it shouldn't be that difficult
13:48Sgeohttps://www.refheap.com/paste/4639
13:48SgeoI should probably really set up a Clojure environment to test that
13:48SgeoI didn't use delivered?
13:50hyPiRion,(let [p (promise)] (deliver p 1) (deliver p 1))
13:50clojurebotnil
13:50hyPiRionHm.
13:50Sgeo,(let [p (promise)] (deliver p 1) (deliver p 1) @p)
13:50clojurebot1
13:51Sgeo,(let [p (promise)] (deliver p 1) (deliver p 2) @p)
13:51clojurebot1
13:51hyPiRionThat's scary.
13:51naegnot all lisp dialects use that much lazy seqs as clojure does, right?
13:51hyPiRionnaeg: True.
13:52naegthanks hyPiRion
13:52Sgeo...I accidentally called it umamb
13:54SgeoIt really should have a way to kill the other threads, hmm
13:54hyPiRionSgeo: Yeah, I know
13:56hyPiRion.interrupt, isn't it?
13:56SgeoI don't know Java.
13:58SgeoMaybe we should be writing a function and then just laying a macro on top of it
13:58FrozenlockI just discovered that I can do `(map :key map)' instead of `(map #(:key %) map). I'm a little ashamed.
13:59Chousukeheh :P
13:59Chousukein general, whenever you do #(foo %) it's replaceable with just foo, unless foo is a macro or a java method
14:00SgeoAnd #(foo bar %) is replaceable with (partial foo bar)
14:00SgeoWell, actually, (partial foo bar) is more general
14:00ChousukeI tend not to use partial
14:00ChousukeI'd just use the anonymous function
14:00hyPiRionIt's a bit slower though, which is kind of sad.
14:00FrozenlockI've never used partial...
14:01Chousukeand re threads, interrupt doesn't actually do anything useful unless the thread is actively checking whether it has been interrupted.
14:01Chousukeor if it's blocking, in which case an exception is thrown in the thread
14:01ChousukeIIRC
14:02SgeoCould use futures...
14:03Chousukewell futures use java threads so the semantics don't really change
14:04michaelr525hello
14:04SgeoChousuke, but could use future-cancel rather than hoping that .interrupt does something
14:08SgeoOr I could just fork another thread that waits on the promise and when the promise is fulfilled kills all the futures
14:12jaleycan 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:12jaleyi.e., how do I know I need a type?
14:19michaelr525hmm
14:20michaelr525how can i add multiple compojure routes to the handler?
14:20michaelr525I mean, i have a function which generates a list of routes which I want to add to (defroutes handler ...)
14:23Sgeohttps://www.refheap.com/paste/4640
14:23SgeoMore stuff I should test if I ever get around to it
14:24SgeoOuch, hmm
14:25Sgeohttps://www.refheap.com/paste/4641
14:25SgeoCloser to correct, because I need to call fun, not deliver fun.
14:26Sgeo*sigh*
14:26SgeoI need to get an environment where I can test this before doing anything else, I think I see another problem
14:41SgeoYou know what, I have Clooj. I'll try it in Clooj.
14:47SgeoAnd Clooj isn't working nicely. Why should it?
14:50SgeoSeems to be working!
14:50Sgeo(unamb (+ 2 2) (* 2 2))
14:50Sgeo4
14:53Sgeoticking, try https://www.refheap.com/paste/4641
14:53SgeoWait, no, don't
14:53Sgeohttps://www.refheap.com/paste/4643 there we go
14:53naegwould 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:54naegit is actually not meant to be read by Clojure programmers btw
14:55casionseems strange that I have to click a link to see the full clojure source, but not the python
14:55naegcasion: oh, I'll add that one too. thanks
14:59naegcasion: or did you mean why I explain the clojure code in such great detail and the python not at all?
15:00uvtcnaeg: 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:00casionnaeg: 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:00casionand the light-dark thing I dislike as well
15:00uvtc(naeg: more on the style: I don't think single-line code snippets need line numbers enabled)
15:00casionthe writing seems clear though
15:01naeguvtc: yes, I tried out that highlight feature of SyntaxHighlighter. If more people tell me this, I'll remove it
15:02naegok, already 4 people complaining about line highlighting - will remove that for sure. and good point uvtc about line numbers
15:03uvtcnaeg: Though I realize you're probably more interested in more substantive comments on your Clojure code. :)
15:03naegcasion: I'm unsure about adding the whole Clojure code inside the blog post, it seems quite long to me already
15:03naeguvtc: 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:04casionnaeg: It looks like it's the same LOC as the python example
15:04casionat the very least, if you're trying to show people clojure, show the whole clojure code.. and link to the python example
15:04casionthat's my thought at least :)
15:05naegcasion: 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:05casionnaeg: you can't do both?
15:05uvtcnaeg: I'd also like to see the complete Clojure program. In one big block, it's easy enough to scroll past. :)
15:05casionmost programming language blog posts and books and tutorials work function by function, then end with the whole thing
15:06naegconvinced, makes sense. will add it
15:09naegand explanations are understandable to you? of course you have to assume you would have no clue about clojure
15:10casionseems ok to me, but I'm no expert by far :)
15:15hughfdjacksonin defrecord, what's the rational behind passing a vector of symbols
15:15hughfdjacksonrather than one of keywords
15:15hughfdjacksongiven that the resultant map uses keywords?
15:17naegthanks for your feedback casion and uvtc
15:31freiksenetwhy are clojure data structures called persistent and not functional?
15:31hughfdjacksonfreiksenet: 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:31freiksenetwouldn't 'functional' be a more correct name?
15:31freiksenetyesyes
15:31freiksenetalso there are non-functional persistent data structures
15:31hughfdjacksoni assume that's cause that's what they do n.n correct me if i'm wrong
15:32freiksenetpersistent is a bigger set than functional
15:32technomancyfreiksenet: "functional" is a property of programs, not data structures.
15:32freiksenettechnomancy: again, that's wrong.
15:32technomancyfreiksenet: OK, that's an interesting opinion.
15:32freiksenetsee landmark book 'pure functional data structures'
15:32freiksenetby Okasaki
15:33hughfdjacksonfreiksenet: i wonder if it's simply because the use of 'persistent data structure' causes less debate ;)
15:33technomancyI suspect the publishers wouldn't have been to keen if he insisted on titling it "Data structures useful for writing purely functional programs."
15:33technomancy*too
15:33gfredericksdoes 'pure functional' in that context refer to the implementation?
15:33freiksenettechnomancy: "Purely functional is a term in computing used to describe algorithms, data structures or programming languages"
15:34gfredericksbecause in that case I don't think clojure's data structures are functional
15:34technomancyanyway, "persistent" has a very clear, specific definition, while "functional" is vague and means different things to different people.
15:36freiksenetgfredericks: depending on how deep you go no data structures are functional :)
15:36freiksenetgfredericks: but that's a valid point
15:36gfredericksfreiksenet: 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:36gfredericksimplementation at any level
15:36casioncalling a data sturcture functional seems odd, since data by definition is not a function
15:37gfrederickscasion: that's an ironic thing to say since some of clojure's data structures are functions :D
15:37technomancywell, maps are functions, as are vectors
15:37technomancylists aren't functions but are persistent
15:37technomancyanyway, it's not a very clear term.
15:38freiksenetboth are not, IMO
15:38gfrederickswhat else might persistent mean?
15:40freiksenethm.
15:40freiksenettechnomancy: gfredericks: I guess you are right
15:40freiksenetthanks
15:44casiongfredericks: it was my understanding that data structures in clojure are classes that encapsulate the data, and an invoke method
15:45casionit's just presented syntactically as the same thing
15:45casionis that incorrect?
15:46gfrederickscasion: I can't figure out what you mean precisely enough to say one way or the other
15:46gfrederickswhat two things are you saying are being presented as the same thing?
15:46casionsay a key in a map
15:47casionthe key is both data and a function (being invoke)
15:47gfredericksyes the fact that these different things are functions is orthogonal to their dataness; and probably not related to the previous discussion
15:48gfredericksbut in the implementation it's one class doing both things
15:48gfredericksthat'd be easier to break apart if they were implemented with types and protocols
15:50casionok, thanks for the clarification
15:56augustlis 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:57gfredericksa handler is a function; so you can give lein-ring a function that does whatever complicated thing you want it to do
15:58gfredericksincluding making new handlers and deferring to them
16:00augustlgfredericks: 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:00gfredericksaugustl: delay is a silghtly simpler mechanism for that kind of thing
16:01augustlnice, looking it up
16:02augustlvery useful. I seem to learn a new function every day :)
16:03augustlhmm, delay doesn't seem to return a function, it returns a ref, right?
16:04augustl..ish. Getting "java.lang.ClassCastException: clojure.lang.Delay cannot be cast to clojure.lang.IFn"
16:04gfredericksa reference that you want to call deref on
16:06augustlseems like lein-ring doesn't support it
16:06augustla defer in my project.clj also causes an error
16:07augustlderef*
16:07gfrederickslein-ring doesn't have to support it
16:07gfredericks(let [my-real-handler (delay (make-handler {}))] (defn my-lein-ring-handler [req] (@my-real-handler req)))
16:08augustlah
16:27muhoowhy the delay?
16:28gfrederickssounded 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:28muhoothanks
16:53bosiewhats the way to test multi threaded apps in clojure?
16:54gfrederickswhat aspect do you want to test?
16:54bosiegfredericks: whether or not i have multi threaded related bugs ;)
16:54gfrederickshow do you tell it is working correctly?
16:55bosiegfredericks: so i don't override data, don't have race-conditions etc
16:56gfredericksthat sounds about as elusive as "I want to make sure there aren't bugs"
16:56bosiegfredericks: well
16:56gfredericksthere are general strategies for avoiding those kinds of things, like using immutable data and pure functions
16:56gfredericksand doing the multithreading at a high level if you can
16:57gfredericksbut if you want to test it, you have to at least have something positive that you're looking for
16:57bosiegfredericks: more wondering how i would even introduce the problems? how would you set it up
16:57gfredericksrun a bunch of threads at the same time doing a bunch of stuff?
16:57chousertests 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:58bosiehm
16:59chouserif 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:00chouserI 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:00bosiegfredericks: 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:00bosiechouser: so what approach do you recommend?
17:01chouserbosie: pure functions on immutable values, so that there's no state changes that can be racing. :-)
17:01gfredericksbosie: 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:01bosiechouser: how would you handle non-pure functions?
17:01bosiechouser: like reading to/from a file?
17:02cshellYou're using multiple threads to write to the same file?
17:02bosiecshell: ideally, guess not ;)
17:02chouserbosie: 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:02cshellwhy not just have one thread responsible for the read/write?
17:03chouserthis 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:03bosiechouser: right
17:04bosiechouser: so basically the 'helper' functions are pure. the rest is impure
17:04bosiecshell: can't keep everything in memory
17:05bosiehm
17:05bosieok
17:05bosiechouser: which also means you don't use datastructures which are implemented in java, right?
17:06chouserbosie: right
17:06bosiechouser: unless they are explicitely thread-safe
17:06chouserwell, not the impure ones. there are a few java libs that implement immutable data types
17:06chouserJoda time, Google collections, etc.
17:06cshellGoogle Guava's collections, right?
17:06chouseryeah
17:08chouserbosie: you can sometimes use lazy seqs if for data that won't fit in memory
17:09chouserAnd 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:09bosiechouser: thats for sure. that is what intrigues me about good ol' clojure
17:11chousermore 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:12gfredericks(-> (read-input) (figure-out-what-to-do) (do-it))
17:12gfrederickswhere all the business logic is in the middle
17:13gfredericksin our case that meant parallelizing the middle piece was easy and not scary
17:18emezeskeThere are strategies you can use to help surface bad threading behavior
17:19emezeskeE.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:19emezeskeNo guarantee that will find bugs, but it does boost confidence that things aren't horribly broken
17:26bosieemezeske: fakely boosting it ;)
17:34uvtcIs there a game lib for use with Clojure, something like SDL? Or do most folks start off with just using Swing?
17:41nz-uvtc: look at game libs for Java
17:42nz-uvtc: there you'll find OpenGL and SDL like stuff
17:44technomancyuvtc: just penumbra, which is unmaintained.
17:44uvtcHm.
17:44technomancyyou can use quil, but it's not really on the same level in terms of performance
17:44bosiechouser: just came to the careers page at lonocloud. how do you do pair programming remotely?
17:45uvtcJust looking for simple not-high-performance 2D-graphics with some sounds.
17:45chouserbosie: we use a custom convenience layer on top of tmux and excellent polycom speakerphones
17:45technomancyuvtc: ah, quil should fit the bill then
17:46bosiechouser: tmux, so you are using vim/emacs?
17:46technomancyit's pretty pleasant to work with
17:46chouserbosie: yes. emacs + evil
17:46bosieok
17:46technomancychouser: is your entire team switched over?
17:47bosiechouser: 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:47chousertechnomancy: 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:47technomancychouser: ah, so you swap it on or off depending on who's driving
17:48bosieok
17:48chousertechnomancy: yeah, C-z toggles off vim bindings when evil is loaded
17:48technomancyseems like you pretty much have to agree on some level of standardization
17:49chouserbosie: 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:49bosiechouser: weird
17:49bosiechouser: but congrats on getting all of them on emacs
17:49chouserwe started with technomancy's starter kit and went from there.
17:49technomancythe 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:50chouserwe're mostly not old emacsers. In fact, almost everyone used vim until learning Clojure, if not later.
17:50bosiechouser: hah. i am in the same boat. waiting to pick up emacs until i know clojure will stick with me ;)
17:51bosiechouser: but at work we have unfortunately a wide range of editors/ides. can't seem to agree on the one thing
17:51chouserbosie: yeah, emacs isn't the panacea that I was hoping for. But with evil in there it's been a much smoother transition.
17:52technomancyyou definitely have to make some hard choices to make remote pairing work
17:52bosiechouser: just out of curiosity. how does evil manage keybindings?
17:52technomancyin most cases the access to a wider talent pool is well-worth it if you can get buy-in
17:52chouserof course now my fingers know a combination of keystrokes that makes me useless in both stock emacs *and* stock vim. :-/
17:52chouserbosie: not sure what you mean.
17:52bosiechouser: 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:53bosieC-c C-f C-b => insert bold face text
17:54chouserah, 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:55chouserthis allows us to use paredit comfortably.
17:55bosiechouser: which is the point… i really don't wanna use emacs bindings ;)
17:55bosiechouser: i much rather press ,fb or sth
17:55chouserour biggest pairing problems are actually around term colors, not key bindings.
17:56bosiek
17:56technomancychouser: people using terminal.app garbage?
17:57chouseroh, it's really hard to place blame. xterm256 vs xterm, dark backgrounds vs. light backgrounds, different emacs themes, etc.
17:57chouserbut sure, gnome term vs. terminal.app probably as well
17:57RaynesEmacs with evil-mode is pretty much the bee's knees.
17:57RaynesAll of the things I liked about Vim and all of the things I like about Emacs.
17:58technomancylight vs dark backgrounds is a pain though
17:58technomancyeveryone just needs to standardize on glasstty and we can move on =)
17:58bosieRaynes: do you ever need to use alt/ctrl like you do in vanilla emacs?
17:58technomancyclojurebot: glasstty?
17:58clojurebotNo entiendo
17:58uvtctechnomancy: thanks for the tip. Will have a look at quil.
17:58technomancyclojurebot: glasstty is a great font for serious hacking: http://sensi.org/~svo/glasstty/
17:58clojurebotYou don't have to tell me twice.
17:59technomancyclojurebot: you say that, but sometimes I do.
17:59clojurebotIt's greek to me.
17:59Raynesbosie: Yes. You don't use evil-mode to replace everything in Emacs. You use it to add things from Vim.
17:59technomancycase closed
17:59bosieRaynes: using emacs with regular keybindings gives me cramps in my hands, so yes, i would add evil to get rid of the keybindings
18:00RaynesI've never had those problems.
18:00RaynesMy ctrl key is my capslock key and it is not even physically possible for me to get a cramp.
18:01bosieRaynes: cramp, carpal tunnel syndrome,.. not sure. but it isn't a nice feeling either way
18:01bosieRaynes: esc is my capslock ;)
18:01RaynesIf you've got your keyboard set up for Vim, chances are Emacs isn't going to work optimally for you.
18:02tos9What's there to set up
18:02RaynesSwitch capslock and ctrl.
18:02bosieRaynes: 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:02bosieRaynes: vim never ever gave me those problems
18:02tos9Raynes: Yeah. I have that for Vim. It works fine for Emacs too.
18:02Raynesbosie: So far you've listed one problem.
18:03bosieRaynes: kinda major....
18:03RaynesOne which I proposed a possible solution to, that you implied you never tried.
18:03bosieRaynes: switching capslock?
18:03bosieRaynes: i have a kinesis keyboard, ctrl is on my homerow
18:03Raynes*shrug*
18:03bosieRaynes: so is alt
18:04RaynesThen I simply don't understand. But hey, I don't have to. You're happy with Vim. :)
18:04bosieRaynes: i am not ;)
18:04technomancyyou get to ignore potential name conflicts if they don't have any github forks and are hosted on a separate runtime, right?
18:04technomancythem's the rules
18:05cshellWhat are the names of those new keyboards which have the keys directly in line with each other? like c3900 or something?
18:05technomancytype matrix is the only one I know of
18:05cshellyeah, that's the one the 2030
18:05cshellthanks technomancy
18:06cshellHas anyone here used one of those?
18:06bosiecshell: give this one a chance, it is awesome http://www.kinesis-ergo.com/advantage.htm
18:07cshellthatnnks, but I've never liked those curvy keyboards
18:07csheller, thanks
18:07cshell:)
18:07bosiek
18:07cshellthe typematrix one looks interesting because of the key placement
18:08cshellbut I never have pain from typing so maybe I don't need one
18:08cshellof either
18:08uvtcI missed most of this conversation, but love the kinesis advantage (formerly "contoured") keyboard.
18:08qmxbosie: these keyboards are scary - I'd rather get an oldy "clicky" IBM
18:08bosieuvtc: yup!
18:09bosieqmx: hehe yea well… just be assured, they aren't what most companies sell as ergonomic (e.g. microsoft, logitech … ) ;)
18:09qmxbosie: no, I'm talking about the oldies :)
18:10casionI use a filco majestouch
18:10casionmuch prefer it over the model m
18:10casionkey laout is colemak, no need for crazy ergo keyboards
18:10bosiegtg cu
18:11uvtcSince casion brings up colemak, anyone using one of these keyboard layouts http://mkweb.bcgsc.ca/carpalx/?full_optimization ?
18:12casionI do
18:12casionI use a modified colemak
18:12casioneasier to just call it colemmak :)
18:12uvtcI'm using dvorak, but was thinking of trying out QFMLWY .
18:12cshellwhat's the difference betwen dvorak and qfmlwy?
18:13casionless finger travel
18:13casionmore home row usage
18:13uvtcQFMLWY is original --- not based on an existing layout.
18:13cshellfor dovrak?
18:13uvtcThere's a plot somewhere on that site ... lessee..
18:13casionuvtc: I use the modified colemak from the carpalx website
18:13casionit's on there somewhere
18:14cshellhow do you guys handel typing on other computers, ones which have standard qwerty?
18:14casionyou just type?
18:14casioni can type normally on colemak, qwerty, dvorak and modified colemak just fine
18:14cshellright, but context switching must cause some challenges, right?
18:15casionnope
18:15uvtccshell: My fingers have long-forgotten qwerty. I hunt-and-peck until I can remap the keys.
18:15uvtcAh, here's the plot I was looking for: http://mkweb.bcgsc.ca/carpalx/?popular_alternatives
18:16nz-what is the home row?
18:18uvtcnz-: depends on the layout. dvorak has aoeu and htns on the home row.
18:21nz-uvtc: so the basically the row in the middle
18:22cshellyeah, i think where your fingers are supposed to rest
18:23uvtcnz-: http://en.wikipedia.org/wiki/Homerow#Home_row
18:57Apage43keyboard talk happened D:
20:47ibdknoxHiring link posted to HN
20:47ibdknoxhere we go
20:47ibdknoxlol
20:47ibdknoxhttp://kodowa.com/jobs
20:48Raynesibdknox: evenin' partner
20:49ibdknoxRaynes: hola
20:49casioneveryone has to be in california
20:50casionand I just learned where soma is
20:51Raynesibdknox: Excited to see what happens when you've got a team.
20:51ibdknoxRaynes: you and me both
20:51ibdknoxlol
20:57brehautibdknox, Raynes: productivity decresses as 2pm meetings take over from writing the codes
21:02ibdknoxbrehaut: :p
21:05timvisheris there an easy way to get `lein ring server` to get me a port that slime can connect to?
21:12xeqifor nrepl you could use https://github.com/cemerick/drawbridge, but not sure what you would do for slime
21:22cshellIs 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:25djanatynis there something like hackageDB for clojure?
21:26djanatynclojars doesn't seem to have an interface for browsing through packages
21:26qmxany reason for clojars having so many -SNAPSHOT packages?
21:27cshellqmx: Continuous Integration builds?
21:27cshelldjanatyn: which packages are you trying to browse?
21:28qmxcshell: 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:28cshellno, same semantics
21:29qmxso, discouraged for serious use
21:29qmx"serious"
21:29djanatyncshell: all of them. I'm just interested in using clojure for something, so I was looking for a fun package
21:29cshellwhat packages are you talkin gabout?
21:29qmxdjanatyn: clojure-toolbox.com has some good tips
21:30csheller, qmx: what packages are you talking about?
21:30cshelldjanatyn: normally you can just browse the source
21:30qmxcshell: several, in one week I bumped in at least 10 that say on their readmes: [foo.bar X.XX-SNAPSHOT]
21:31cshelldjanatyn: the clojure core has documentation you can browse
21:31qmxthat's why I'm asking
21:31djanatyncshell: I mean browsing a list of all packages on clojars
21:31tomojdjanatyn: well.. https://clojars.org/repo/ :)
21:31cshellqmx: semantics are the same, I haven't seen a useful library on clojars that didn't have a release version
21:31tomojalso https://clojars.org/repo/all-jars.clj
21:31qmxcshell: ha! so we're on the same page :)
21:31tomojas if that's helpful..
21:32djanatyntomoj: thanks!
21:32cshellqmx: I don't like to use snapshots unless there's a critical bug fix in one that's impacting me
21:32tomojdjanatyn: also note `lein2 search` (which seems to only work inside a project)
21:33cshellqmx: and then you can shoot the author an email to release it, or you can release one yourself if it's on github
21:42cshellcan someone please tell me the difference between passing the function x by its symbol and passing it with #'x
21:42cshellI 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:44tomoj#'x is reader shorthand for (var x), which returns the var
21:44tomoj(def x 3) and then #'x return the same thing
21:45tomojyou can deref the var to get its value: @#'x
21:45tomojbut vars also implement IFn by derefing and calling that
21:46tomojso (#'inc 3) works
21:46tomojmore about vars: http://clojure.org/vars
21:46cshellRight, but if I put a closure over a function referenced by the symbol only, then try to hook it, it doesn't work
21:47tomojby hook it do you mean redef it?
21:47cshellUsing the Robert Hooke library, so that's what is happening right? It's redefining the var
21:47cshellwhen i add the hook
21:48tomojhmm
21:48tomoj(do (def foo (constantly 3)) (def bar #(foo)) (def foo (constantly 4)) (bar))
21:48tomojI get 4
21:48cshellbut even if I load the hooks first, the closure seems get its own binding to the function
21:48cshellunless i pass in the var
21:49tomojbest chance would be to paste an example somewhere if you can
21:50tomojoh, maybe I see
21:51cshellit looks like the hook library is altering the root binding
21:53tomojsomething like this? https://gist.github.com/d4783314ac651d0c06b3
21:54tomoj(substitute redef for hooking)
21:54cshellyeah, i think that's very similar
21:54tomojthe reason that returns 3 is that (foo bar) passes the value of bar at that time to foo
21:54tomojthe value of bar is a function
21:55tomojwhen you hook you don't change the function, you just point the var at the new hooked function
21:55cshellso the closure keeps the original value of the var?
21:55cshellbut if you pass (foo #'bar) it will work right?
21:56tomojright
21:56tomojpassing the var in instead of the function would make sense in an example like that if you want to hook
21:56cshellyeah, that's what I'm hitting up against
21:56cshellI notice that, in cemerick's book, he uses #' when referencing function vars - is this more idiomatic?
21:58tomojyou mean in english text?
21:59cshellI mean, it's probably better to pass my vars (which contain functions) by passing the var itself, ie #'
21:59tomojI 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:59clojurebotmap is an evil genius.
22:00cshellSo, if you do just (map inc coll) you can't hook the inc?
22:01tomojright, unless it was hooked before (map inc coll) was evaluated
22:02cshellokay, that's a lot to think about - I appreciate your help, tomoj
22:03cshellthank you
22:04tomojI don't think I fully understand all the details
22:04tomoj&(do (def bar (constantly 3)) (defn foo [] (bar)) (def bar (constantly 4)) (foo))
22:04lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
22:04tomojoright
22:07tomojI guess I understand that operationally, but I don't know how to explain it
22:08cshellyeah, 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:08amalloytomoj: (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:08cshellamalloy: and that's what happens with the closure, right? it sets a binding within that closure?
22:09amalloyi don't have enough context to answer that question
22:10tomojamalloy: I see, thanks
22:10tomojin my gist, (foo bar) derefs #'bar immediately and foo just receives the value
22:11tomojso any changes to #'bar afterward don't matter
22:56SgeoHmm
22:56SgeoI think unamb might be less useful in Clojure than in Haskell
22:57SgeoIt's hard to do variadic or with unamb directly
22:59tomojdo you mean amb?
23:00tomojI don't see why you'd want a variadic or in clojure with unamb-like semantics
23:01Sgeotomoj, short-circuiting in all directions isn't interesting?
23:01Sgeohttps://www.refheap.com/paste/4643
23:03gfredericksit's never been clear to me if future-cancel will interupt if the thing has started already
23:04tomojthe 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:04amalloygfredericks: usually. no guarantees
23:04tomojoh I see you specify "give the same value"
23:05gfredericksamalloy: so it could conceivably run forever and never be interrupted?
23:05amalloyyes
23:06amalloyeg, (loop [] (recur)) can't be interrupted, because there's no system call for the jvm to insert an InterruptedException into
23:06gfredericksI see.
23:06gfrederickslame jvm. I hope you're getting some huge performance boost out of this.
23:07amalloycorrectness boost, if i understand correctly. Thread/stop has been around since 1.0, and was deprecated because it's terrible for system stability
23:10RaynesSure wish they hadn't done that.
23:13gfredericks&(loop [] (recur))
23:14lazybotExecution Timed Out!
23:17SgeoHmm, how dangerous is my unamb considering the possibility of some threads never actually cancelling?
23:17Sgeo(Memory-wise, I mean)
23:24SgeoI'm beginning to hate the JVM more and more