2012-08-26
| 00: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. |
| 00:11 | casion | Clojure Programming or Programming Clojure |
| 00:11 | synfinat_ | cool, i'll take a look at those |
| 00:11 | casion | if you're more used to ruby, I'd think clojure programming is probab ly better |
| 00:12 | synfinat_ | perfect |
| 00:12 | casion | for me, being used to C, I've found more benefit in programming clojure |
| 00:12 | casion | just my opinion, they're both very good books |
| 00:12 | synfinat_ | we'll i'm equally fulent in those first three, although seems clojure is closer to ruby |
| 00:15 | gfredericks | clojurebot: stuartsierra is authoritative enough |
| 00:15 | clojurebot | Ik begrijp |
| 01:09 | emezeske | $findfn 1 1 |
| 01: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 |
| 01:09 | emezeske | $findfn [1 1] [1 1] |
| 01: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 |
| 01:09 | emezeske | $findfn inc 1 5 |
| 01:09 | lazybot | [] |
| 01:09 | emezeske | $findfn 1 inc 5 |
| 01:09 | lazybot | [] |
| 01:09 | emezeske | $findfn [inc 1 5] 5 |
| 01:09 | lazybot | [clojure.core/last clojure.core/peek] |
| 01:12 | emezeske | Is there a clojure.core function that, given a function and a number, composes that function recursively that many times? |
| 01:12 | emezeske | E.g. (whatever inc 3) -> (inc (inc (inc %))) |
| 01:15 | emezeske | 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 |
| 01:16 | metellus | something with iterate, probably |
| 01:18 | emezeske | Yeah, (nth (iterate inc 5) 3) does the trick. That's the most concise I've come up with |
| 01:21 | pandeiro | emezeske: repeatedly doesn't do it? |
| 01: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 |
| 01:24 | pandeiro | emezeske: yah nvm, i was confusing with iterate anyway |
| 01:25 | emezeske | I think maybe it's not a common thing to want to do |
| 01:25 | amalloy | emezeske: it's common enough, and iterate is the right answer |
| 01:26 | amalloy | if it galls you for some reason, you can do something silly like ##((apply comp (repeat 5 inc)) 1) |
| 01:26 | lazybot | ⇒ 6 |
| 01:27 | emezeske | Heh, no gall for me. I just wanted to make sure I wasn't missing a better way to do it. |
| 01:27 | emezeske | I just had that inkling that maaaaybe c.c had composed that already :) |
| 01:32 | technomancy | (apply comp (repeat inc 5)) is clearer imo |
| 01:33 | technomancy | maybe it's just me |
| 01:34 | amalloy | some of that's because of the awful argument order for nth |
| 01:34 | amalloy | like (->> 1 (iterate inc) (nth 5)) would be pretty nice |
| 01:53 | Sgeo | How often does jimduey come here? |
| 01:56 | grisu | |
| 01:57 | emezeske | Sgeo: Is that his irc nick? |
| 01:57 | Sgeo | Yes, apparently. |
| 01:57 | Sgeo | At least it was when he msg'd me a while ago |
| 01: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 |
| 02:01 | amalloy | $seen jimduey |
| 02:01 | lazybot | jimduey was last seen quitting 1 day and 6 hours ago. |
| 02:39 | Sgeo | I hate protocols. |
| 02:39 | Sgeo | Suppose I make a library with protocols, and allow users to extend stuff via the usual way to do that with protocols. |
| 02:40 | Sgeo | 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. |
| 02:41 | Raynes | You hate protocols because you don't know when to use them vs multimethods? |
| 02: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) |
| 02:43 | Raynes | Protocols are like typeclasses. |
| 02:47 | Sgeo | Haskell-style typeclasses, even with multiparamtypeclasses (which protocols are not like) are insufficient as far as I'm concerned |
| 02:48 | amalloy | so...don't use them |
| 03:02 | magopian | it seems it's not possible to use "apply" with "or", how would i go about that? |
| 03:02 | amalloy | &(doc some) |
| 03: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)" |
| 03:02 | magopian | (i'm mapping a function to a seq, which returns a seq of booleans, and i need to "or" them) |
| 03:02 | magopian | ah :) |
| 03:02 | magopian | sure, thanks amalloy :D |
| 03:03 | magopian | (should have thought about that... :) |
| 03:05 | Sgeo | &(apply (partial some identity) '(true true false)) |
| 03:05 | lazybot | clojure.lang.ArityException: Wrong number of args (4) passed to: core$some |
| 03:06 | Sgeo | &((partial some identity) '(true true false)) |
| 03:06 | lazybot | ⇒ true |
| 03:06 | Sgeo | I'm ... not entirely sure what I was thinking |
| 03:07 | Sgeo | Oh, that some took a variadic amount of arguments as though it was or |
| 03: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. |
| 03:13 | Cr8 | I suppose I ought to dogfood that |
| 03:24 | Cr8 | oh |
| 03:24 | Cr8 | I can't spell. |
| 03:27 | Cr8 | antares_: cool, got my project using the couchbase connection now :) |
| 04:09 | magopian | stack overflows happen when there's non tail recursive calls, is that right? |
| 04:10 | magopian | 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 :/ |
| 04:10 | magopian | the problem: http://www.4clojure.com/problem/89 |
| 04:11 | magopian | my solution: https://friendpaste.com/7QiF9pQ1oe3J5KgTEKwDII |
| 04:12 | Sgeo | Do note that Clojure isn't inherently tail-recursive, although there are ways around that |
| 04:24 | Cr8 | magopian: the stack will overflow even if your recursive calls are in tail position |
| 04:24 | Cr8 | you have to explicilty use (recur) to avoid stack blowup |
| 04:25 | magopian | oh really? didn't know that |
| 04:25 | magopian | nice to know ;) |
| 04:25 | magopian | i can't see a way to use recurse with my actual solution, will have to think about something new :/ |
| 04:26 | Cr8 | (recur) is basically: switch in these values and GOTO the last recur point |
| 04:26 | Cr8 | which is either the top of the fn or the nearest loop |
| 04:26 | Sgeo | Cr8, too bad it can't also be used to effectively GOTO a different function |
| 04:27 | Cr8 | that's the reason for recur |
| 04:27 | Cr8 | if you could jump to another function that way then you could just do actual tail call elimination |
| 04:28 | michaelr` | good morning |
| 04:29 | Cr8 | magopian: perhaps you can wrap it up with trampoline |
| 04:29 | Cr8 | http://clojuredocs.org/clojure_core/clojure.core/trampoline |
| 04:41 | magopian | Cr8: i doubt it, but i'll try ;) |
| 04:43 | Raynes | Sgeo: That's what trampoline is for. |
| 06:01 | Cr8 | aw, can't use future on 4clojure =P |
| 06:31 | Sgeo | Cr8, o.O why not? |
| 06:31 | Cr8 | i don't knwow |
| 06:32 | Cr8 | doesn't matter, my solution was wrong anyway |
| 06:32 | Sgeo | TryClj doesn't like it either |
| 06:32 | Sgeo | java.lang.SecurityException: You tripped the alarm! future-call is bad! |
| 06:32 | Sgeo | Clojure> |
| 06:33 | Sgeo | I think if I made a ClojureNomic, I might want to make my own sandbox |
| 06:33 | Sgeo | But, I'm fairly convinced that newLisp is a better language for a nomic than Clojure |
| 06:33 | Sgeo | And it's now starting to sink in that "better for a codenomic" != "better general purpose language" |
| 06: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. |
| 06:34 | Sgeo | I assume you could build your own futures based on promises + Thread. and start. |
| 06:35 | Sgeo | erm, .start |
| 06:36 | Cr8 | I would expect that Thread. would also be a no-no |
| 06:36 | Sgeo | Cr8, works for me in TryClk |
| 06:36 | Sgeo | erm, TryClj |
| 06:37 | Cr8 | hm. Does it keep track of the threads you start and forcibly stop them? |
| 06:38 | Sgeo | No idea |
| 06:40 | Sgeo | Crud, I don't think TryClj likes macros. |
| 06:40 | Raynes | Cr8: Yes. |
| 06:40 | Sgeo | No biggie, my-future can take a function of 0 arguments instead. |
| 06:40 | Cr8 | neat |
| 06:42 | Cr8 | I guess that's why agents are also bad |
| 06:42 | Cr8 | since they use a threadpool that the sandbox doesn't manage |
| 06:42 | Sgeo | (defn my-future [f] (let [p (promise)] (.start (Thread. #(deliver p (f)))) p)) |
| 06:43 | Sgeo | Note that my-future is a function that takes in a function, rather than being a simple macro |
| 06:43 | Sgeo | So (my-future #(+ 1 1)) instead of (future (+ 1 1)) |
| 06:55 | Cr8 | whee, got it |
| 06:56 | Raynes | I doubt it. |
| 06:57 | Raynes | You can't define macros on 4clojure, and he said his solution was fundamentally incorrect anyways. |
| 06:58 | Sgeo | my-future isn't a macro (specifically for that reason), but yeah, fundamentally incorrect means I'm probably not helpful |
| 07:01 | Raynes | Oh, right. |
| 07:01 | Raynes | I didn't mean to imply you were being unhelpful. |
| 07: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 |
| 07:03 | Sgeo | Although I tried to write a macro-writing macro in CL once, it didn't work out too well |
| 07:04 | Sgeo | Also, I'd need to consider the role of arguments |
| 07:09 | Sgeo | I still need to try to set up a sane Clojure environment on my comp |
| 08: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. |
| 08:33 | tomsw | I get a ClassNotFoundException for com.sun.jdi.VirtualMachine whenever I try running lein ritz |
| 08:33 | tomsw | does anyone know how to fix this with lein2? |
| 08:42 | tomsw | ah, realised that JAVA_HOME was pointing at the Oracle jdk but that /usr/bin/java was still pointing at the OpenJDK one. |
| 08:58 | hyPiRion | Man, common lisp's format (cl-format) is like a language in itself. |
| 08:58 | hyPiRion | ,(require 'clojure.pprint) |
| 08:58 | clojurebot | nil |
| 09: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") |
| 09:01 | clojurebot | "Two cows and three pigs." |
| 09: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") |
| 09:01 | clojurebot | "" |
| 09: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") |
| 09:01 | clojurebot | "Two cows" |
| 09:01 | Bronsa | wtf |
| 09:02 | Sgeo | Oh cool, Clojure has a cl-format thing |
| 09: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") |
| 09:02 | clojurebot | "Two cows and one pig." |
| 09:02 | Sgeo | That's one less thing from CL I'll miss |
| 09:02 | hyPiRion | Sgeo: I was so happy when I found it. |
| 09:03 | Sgeo | Things I'll still miss: No JVM, CLOS possibly (not sure), condition system absolutely. |
| 09:04 | Sgeo | Not setf as such, but it would be nice to have a functional equivalent... instead of mutating something it could give a modified copy |
| 09:06 | hyPiRion | Sgeo: I believe multimethods is more flexible than CLOS |
| 09:06 | hyPiRion | Though I don't know if the efficiency is as nice. |
| 09:06 | Sgeo | hyPiRion, I believe that they're fakable at least a little in CLOS |
| 09:07 | hyPiRion | Yeah, probably. |
| 09:07 | hyPiRion | It's completely doable, so. |
| 09: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, |
| 09:11 | Sgeo | Anyways, there's an easier way to write domonad |
| 09:11 | Sgeo | At least I believe so |
| 09:12 | Sgeo | Oh, I'd also need to handle :when and :let |
| 09:21 | xeqi | monad comprehension? |
| 09:28 | Sgeo | I'm starting to see that it's fine as it is |
| 09:29 | hyPiRion | heh |
| 09:31 | Sgeo | I'm not entirely sure why this person uses symbol macros and the like when, afaict, dynamically-scoped variables would work fine. |
| 09:32 | gfredericks | this person? |
| 09:33 | Sgeo | https://github.com/clojure/algo.monads/blob/master/src/main/clojure/clojure/algo/monads.clj |
| 09:33 | Sgeo | 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 | duck1123 | 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 | Sgeo | ^^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 | cshell | 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 | cshell | 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 | michaelr` | web apps |
| 12:03 | michaelr` | 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 | michaelr` | 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 | hyPiRion | 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 | ticking | hyPiRion, semantically it is more of a erlang machine with s-expressions anyway ^^ |
| 12:25 | hyPiRion | That's really sweet. |
| 12:28 | hyPiRion | 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 | hyPiRion | /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 | ticking | 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 | ticking | hyPiRion, I wish we had that for lisps ^^ |
| 12:37 | hyPiRion | ticking: I wish we had a lot for lisps. |
| 12:39 | hyPiRion | 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 | 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 | Sgeo | 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 | gfredericks | 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 | gfredericks | 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 | gfredericks | 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 | gfredericks | 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 | Sgeo | 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 | ticking | 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 | ticking | 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 | ticking | 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 | hyPiRion | 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 | Sgeo | 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 | ticking | Sgeo, academic muscle training, and fun ^^? |
| 13:20 | Sgeo | Has anyone written unamb for Clojure? |
| 13:21 | Sgeo | Someone should |
| 13:22 | Sgeo | 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 | Sgeo | Or maybe not |
| 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 | ticking | 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 | Sgeo | (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 | ticking | 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 | ticking | 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 | ticking | 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:30 | ahihi2 | I would just like to point out that there is nothing impure about monads |
| 13:30 | ahihi2 | 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 | Sgeo | Yeah, futures and promises. |
| 13:33 | Sgeo | 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 | ahihi2 | more specifically, _execution_ of IO is impure |
| 13:34 | ahihi2 | 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 | Sgeo | 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 | ticking | 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 | ticking | Sgeo, I really like emacs with the lively package |
| 13:40 | ticking | 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 | Sgeo | I should probably really set up a Clojure environment to test that |
| 13:48 | Sgeo | 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 | Sgeo | It really should have a way to kill the other threads, hmm |
| 13:54 | hyPiRion | Sgeo: Yeah, I know |
| 13:56 | hyPiRion | .interrupt, isn't it? |
| 13:56 | Sgeo | I don't know Java. |
| 13:58 | Sgeo | 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 | Chousuke | 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 | Sgeo | Well, actually, (partial foo bar) is more general |
| 14:00 | Chousuke | I tend not to use partial |
| 14:00 | Chousuke | 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 | Chousuke | or if it's blocking, in which case an exception is thrown in the thread |
| 14:01 | Chousuke | 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: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 | jaley | i.e., how do I know I need a type? |
| 14:19 | michaelr525 | hmm |
| 14:20 | michaelr525 | how can i add multiple compojure routes to the handler? |
| 14:20 | michaelr525 | 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 | Sgeo | More stuff I should test if I ever get around to it |
| 14:24 | Sgeo | Ouch, hmm |
| 14:25 | Sgeo | https://www.refheap.com/paste/4641 |
| 14:25 | Sgeo | Closer to correct, because I need to call fun, not deliver fun. |
| 14:26 | Sgeo | *sigh* |
| 14:26 | Sgeo | I need to get an environment where I can test this before doing anything else, I think I see another problem |
| 14:41 | Sgeo | You know what, I have Clooj. I'll try it in Clooj. |
| 14:47 | Sgeo | And Clooj isn't working nicely. Why should it? |
| 14:50 | Sgeo | Seems to be working! |
| 14:50 | Sgeo | (unamb (+ 2 2) (* 2 2)) |
| 14:50 | Sgeo | 4 |
| 14:53 | Sgeo | ticking, try https://www.refheap.com/paste/4641 |
| 14:53 | Sgeo | Wait, no, don't |
| 14:53 | Sgeo | 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 | naeg | 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: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 | casion | 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 | naeg | 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 | naeg | 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 | casion | 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 | casion | 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 | naeg | 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 | hughfdjackson | rather than one of keywords |
| 15:15 | hughfdjackson | 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 | freiksenet | yesyes |
| 15:31 | freiksenet | 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 | freiksenet | 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 | technomancy | *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 | freiksenet | 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 | gfredericks | 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 | technomancy | lists aren't functions but are persistent |
| 15:37 | technomancy | 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 | freiksenet | technomancy: gfredericks: I guess you are right |
| 15:40 | freiksenet | 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 | casion | it's just presented syntactically as the same thing |
| 15:45 | casion | 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 | gfredericks | what two things are you saying are being presented as the same thing? |
| 15:46 | casion | say a key in a map |
| 15:47 | casion | 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 | gfredericks | but in the implementation it's one class doing both things |
| 15:48 | gfredericks | 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 | gfredericks | 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 | augustl | very useful. I seem to learn a new function every day :) |
| 16:03 | augustl | hmm, delay doesn't seem to return a function, it returns a ref, right? |
| 16:04 | augustl | ..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 | augustl | a defer in my project.clj also causes an error |
| 16:07 | augustl | deref* |
| 16:07 | gfredericks | lein-ring doesn't have to support it |
| 16:07 | gfredericks | (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 | gfredericks | and doing the multithreading at a high level if you can |
| 16:57 | gfredericks | 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 | chouser | 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 | bosie | 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 | bosie | 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 | bosie | chouser: so basically the 'helper' functions are pure. the rest is impure |
| 17:04 | bosie | cshell: can't keep everything in memory |
| 17:05 | bosie | hm |
| 17:05 | bosie | ok |
| 17:05 | bosie | 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 | chouser | Joda time, Google collections, etc. |
| 17:06 | cshell | Google Guava's collections, right? |
| 17:06 | chouser | yeah |
| 17:08 | chouser | bosie: you can sometimes use lazy seqs if for data that won't fit in memory |
| 17:09 | chouser | 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:12 | gfredericks | (-> (read-input) (figure-out-what-to-do) (do-it)) |
| 17:12 | gfredericks | where all the business logic is in the middle |
| 17:13 | gfredericks | 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 | emezeske | 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 | emezeske | 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 | nz- | 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 | bosie | 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 | bosie | 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 | chouser | 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 | bosie | 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 | chouser | 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 | bosie | 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 | chouser | 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 | 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 | technomancy | 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 | Raynes | 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 | bosie | 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 | bosie | 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 | bosie | 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 | technomancy | 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 | cshell | thanks technomancy |
| 18:06 | cshell | 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 | cshell | er, thanks |
| 18:07 | cshell | :) |
| 18:07 | bosie | k |
| 18:07 | cshell | the typematrix one looks interesting because of the key placement |
| 18:08 | cshell | but I never have pain from typing so maybe I don't need one |
| 18:08 | cshell | 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 | bosie | 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 | casion | much prefer it over the model m |
| 18:10 | casion | 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 | casion | I use a modified colemak |
| 18:12 | casion | 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 | casion | 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 | casion | 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 | casion | 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 | uvtc | 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 | ibdknox | here we go |
| 20:47 | ibdknox | lol |
| 20:47 | ibdknox | 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 | casion | 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 | ibdknox | 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 | djanatyn | 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 | cshell | 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 | qmx | "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 | cshell | 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 | cshell | can someone please tell me the difference between passing the function x by its symbol and passing it with #'x |
| 21:42 | cshell | 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 | tomoj | (def x 3) and then #'x return the same thing |
| 21:45 | tomoj | you can deref the var to get its value: @#'x |
| 21:45 | tomoj | but vars also implement IFn by derefing and calling that |
| 21:46 | tomoj | so (#'inc 3) works |
| 21:46 | tomoj | 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 | cshell | when i add the hook |
| 21:48 | tomoj | hmm |
| 21:48 | tomoj | (do (def foo (constantly 3)) (def bar #(foo)) (def foo (constantly 4)) (bar)) |
| 21:48 | tomoj | 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 | cshell | unless i pass in the var |
| 21:49 | tomoj | best chance would be to paste an example somewhere if you can |
| 21:50 | tomoj | 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 | tomoj | (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 | tomoj | the value of bar is a function |
| 21:55 | tomoj | 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 | cshell | but if you pass (foo #'bar) it will work right? |
| 21:56 | tomoj | right |
| 21:56 | tomoj | 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 | cshell | 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 | cshell | thank you |
| 22:04 | tomoj | I don't think I fully understand all the details |
| 22:04 | tomoj | &(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 | tomoj | 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 | tomoj | in my gist, (foo bar) derefs #'bar immediately and foo just receives the value |
| 22:11 | tomoj | so any changes to #'bar afterward don't matter |
| 22:56 | Sgeo | Hmm |
| 22:56 | Sgeo | I think unamb might be less useful in Clojure than in Haskell |
| 22:57 | Sgeo | It's hard to do variadic or with unamb directly |
| 22:59 | tomoj | do you mean amb? |
| 23:00 | tomoj | 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 | Sgeo | 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 | amalloy | 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 | gfredericks | lame jvm. I hope you're getting some huge performance boost out of this. |
| 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 | Sgeo | (Memory-wise, I mean) |
| 23:24 | Sgeo | I'm beginning to hate the JVM more and more |