2011-12-05
| 01:02 | rads | also why do fully qualified keywords always give the user namespace in clojurescript? |
| 01:20 | sunng | it looks a strange behavior when using `case`: |
| 01:20 | sunng | ,(let [c (int 1)] (case c (int 1) "matches")) |
| 01:20 | clojurebot | "matches" |
| 01:21 | sunng | ,(let [c (short 1)] (case c (short 1) "matches")) |
| 01:21 | clojurebot | "matches" |
| 01:21 | sunng | ,*clojure-version* |
| 01:21 | clojurebot | {:major 1, :minor 3, :incremental 0, :qualifier nil} |
| 01:21 | sunng | wow, I think it's a bug in clojure 1.2 and fixed in 1.3 |
| 03:12 | amalloy | sunng: the test-expressions in case clauses have to be compile-time constants; i believe 1.3 made it possible for more things to be regarded as constants. but in general, ##(case 1 (2 1) "either 2 or 1") is how lists are supposed to be used in a case expression |
| 03:12 | lazybot | ⇒ "either 2 or 1" |
| 03:16 | sunng | amalloy: I just find that in clojure 1.2 (case (int 1) (int 1) "ok") could return "ok" but (case (short 1) (short 1) "ok") failed. The inconsistency just confuses me a lot. |
| 03:16 | amalloy | &(hash (short 1)) |
| 03:16 | lazybot | ⇒ 1 |
| 05:11 | ambrosebs | I want to convert (fn. [[a :- type1] [b :- type2]] ...) to (fn [a b] ..) , with (meta a) = {::type type1} |
| 05:11 | ambrosebs | any suggestions as to how to go about this? |
| 05:11 | ambrosebs | also the more general case of the multi-arity syntax |
| 05:12 | ambrosebs | I would use assoc but it doesn't work with lists |
| 05:15 | ambrosebs | nvm, forgot about map :) |
| 05:30 | siancu | morning |
| 06:01 | triyo | I have a list of maps that I wish to merge; merge as in structural merge. Example [{:cons_data {:day {:cost {:total {} :data {}}}}} {:cons_data {:day {:volume {:total {} :data {}}}}}]. In this case, I'd expect the :cost {} and :volume nodes to be merged in to a single list. However, what happens is that the second map's :volume becomes a member but :cost node doesn't appear at all in the merged map. |
| 06:01 | triyo | *single list = I mean into the merged map |
| 06:05 | triyo | Hm, it seems that merge with is what I'm after. |
| 06:06 | triyo | *merge-with |
| 06:10 | Chousuke | triyo: if you need recursive mergeing then you can write a function that uses merge-with to merge the map using itself as the merge function :P |
| 06:11 | triyo | hehe, talking about eating your own dog food |
| 06:11 | triyo | :_) |
| 06:11 | Chousuke | Just don't forget the base case |
| 06:12 | triyo | Hehe, yip wont forget. thx |
| 06:13 | triyo | There is something I remember in contrib right the does deeper merge? |
| 06:14 | triyo | yip, deep-merge-with |
| 06:15 | raek | triyo: if the structure is small enough, it might be easy to just use destructuring: (let [[{{{cost :cost} :day} :cons_data} {{{volume :volume} :day} :cons_data}] m] {:cons_data {:day {:cost cost, :volume volume}}}) |
| 06:16 | raek | where m is your pair of maps |
| 06:18 | triyo | Its not necessary a pair of maps. Its nondetermanistic |
| 06:21 | raek | are there any other keys at the same level of :cons_data and :day? |
| 06:26 | triyo | yip, there will be other timespans: week, month, etc. |
| 06:27 | triyo | deep-merge-with seems to work as it does recursive merge.... Only thing I'm thinking about is what should by function look like... |
| 06:32 | triyo | No clashing occurs on my end except for the start_date and end_date that are under :day. However those date are the same in the maps so something simple as (fn [l r] l) will do |
| 08:08 | TimMc | Raynes: No plans, just following the examples in the blog post. |
| 09:38 | xian | Hi. I'm using some Java code in a Clojure/leiningen project. The Java code requires an external jar which is (of course) not on the leiningen classpath. Since it is not obvious how to alter the classpath of a leiningen project I am looking for another way to make my Java code accessible from Clojure (putting the jar in my_project/resources didn't help). |
| 09:43 | xian | Basically, I'm looking for a way to add a local jar as dependency for the leiningen project. |
| 09:44 | raek | xian: first, have you checked if this "external jar" is in the maven repo? |
| 09:44 | raek | (seach engine: http://jarvana.com/) |
| 09:45 | raek | in case the java code is your own and small, you might want to include it in your clojure project (leiningen can build java code too) |
| 09:47 | raek | the last resort is to put the jar file in the lib/ directory and add :disable-deps-clean false to the project.clj file. there is usually a better way than this to solve the problem, though |
| 09:49 | raek | if the java code is it's own project, you should really make an artifact for it so that you can use it the usual way (add it as a dependency) |
| 10:11 | xian | raek: My dependency is the tools.jar from the JDK distribution (which I need for some JDI interaction). |
| 10:17 | xian | So it's not in the maven repo. |
| 10:18 | TimMc | xian: You can add it as an extra classpath element in your project.clj. |
| 10:19 | raek | looks like that .jar is usually declared with a special systemPath option in maven (which I don't think Leiningen supports) |
| 10:20 | TimMc | xian: https://github.com/technomancy/leiningen/blob/1.x/sample.project.clj |
| 10:21 | TimMc | :extra-classpath-dirs |
| 10:21 | raek | so in this case maybe :extra-classpath-dirs ["path/to/tools.jar"] is the best you can do |
| 10:22 | raek | this path depends on which OS you have, so this will be messy when/if you try to work on this project on another computer |
| 10:22 | TimMc | clojurebot: sample project |is| https://github.com/technomancy/leiningen/blob/1.x/sample.project.clj |
| 10:22 | clojurebot | You don't have to tell me twice. |
| 10:34 | lemoq | hi folksk |
| 10:35 | lemoq | got a question: how do i add the content of a seq to an exception? something like (throw (Exception. "elements in seq: " theseq)), where it lists all elements in theseq?? |
| 10:35 | lazybot | lemoq: What are you, crazy? Of course not! |
| 10:38 | joegallo | ,(doc prn-str) |
| 10:38 | clojurebot | "([& xs]); prn to a string, returning it" |
| 10:38 | erujolc | is there an issue with documentation being out of date: http://clojure.org/vars (a tutorial that is probably high traffic for beginners) that wont work with clojure 1.3 due to not being declare dynamic |
| 10:38 | joegallo | so, for instance, you might do something like (appy prn-str the-seq) |
| 10:40 | joegallo | erujolc: specifically the part about (binding [x 2 y3] (+ x y))? |
| 10:40 | joegallo | s/y3/y 3/ |
| 10:42 | Raynes | &(str "Exception and stuff: " (prn-str [1 2 3])) |
| 10:42 | lazybot | ⇒ "Exception and stuff: [1 2 3]\n" |
| 10:43 | Raynes | &(str "Exception and stuff: " (apply prn-str [1 2 3])) |
| 10:43 | lazybot | ⇒ "Exception and stuff: 1 2 3\n" |
| 10:43 | erujolc | joegallo, i mean that the example wont work |
| 10:43 | erujolc | you need to declare the vars with (def ^:dynamic x 1) |
| 10:43 | Raynes | lemoq: Pick your poison. |
| 10:43 | erujolc | for example |
| 10:44 | lemoq | Raynes, joegallo, thanks, prn-str perfectly does the job |
| 10:46 | joegallo | erujolc: right, that's what i was asking -- was that the problematic part of the example? |
| 10:46 | joegallo | and your answer is yes |
| 10:47 | erujolc | but theres more...http://ideone.com/EAthN |
| 10:48 | erujolc | future is in another thread so I expected the out to be 42nill not 44nil |
| 10:50 | xian | raek, TimMc: Thanks, that works nicely. I don't worry too much about different OSes.. |
| 10:51 | ckirkendall` | erujolc: the future was created under a given binding thus inheriting its thread locals for those bindings. |
| 10:52 | ckirkendall` | erujolc: Its my understanding the bindings apply to all child threads created inside the binding. |
| 10:57 | erujolc | ckirkendall`, that would make sense but cant see this documented anywhere |
| 10:57 | ckirkendall` | erujolc: I am trying to validate but I believe bindings use InheritableThreadLocal |
| 11:16 | ckirkendall` | eurjolc: It doesn't using the built in InheritableThreadLocal but it does seem to implement a custom form of inheritance by passing a copy of the parent bindings into binding frame. |
| 11:19 | erujolc | thanks for the clarification, it does seem to make sense when I think about it a bit longer |
| 11:24 | Raynes | I feel so powerful to be able to release marginalia to clojars. |
| 11:24 | michael_campbell | Good deal with Manning's "deal of the day" today. |
| 11:25 | cemerick | Raynes: when did that happen? |
| 11:26 | cemerick | squeaky wheel effect? ;-) |
| 11:26 | Raynes | cemerick: Fogus and I had a night of passion at the conj. |
| 11:26 | Raynes | Or, he just got tired of me whining at him to release new snapshots. |
| 11:26 | cemerick | Between him and the no starch guys, you really get around! |
| 11:26 | michael_campbell | man, I'm not sure if I'm happy or sad that I just ate, and read that |
| 11:27 | Raynes | cemerick: It took me 30 minutes to tone that tweet down enough to make it even remotely acceptable. |
| 11:27 | Raynes | You should have seen the first draft. |
| 11:27 | cemerick | Raynes: so, we'll have indexes in marg output soon? |
| 11:27 | Raynes | Indexes? |
| 11:29 | Raynes | cemerick: Indexes like outlines? Like on http://jedahu.github.com/story/ |
| 11:29 | cemerick | yeah; indexes, outlines, whatever |
| 11:30 | Raynes | I hope so. I made an issue about it and story, but no responses so far. I'm not sure where one would fit in marg output. If fogus is really attached to the docco format, I bet we're screwed. |
| 11:31 | Raynes | Story is pretty great though. I think it is an excellent compromise between the marginalia-style literate programming and the API-docish stuff that autodoc brings to the table. |
| 11:31 | cemerick | That's closer to what I really want. |
| 11:31 | cemerick | esp. an index that is fixed to the top, just like the ToC in story. |
| 11:31 | Raynes | Me too. |
| 11:32 | Raynes | The one on the left? |
| 11:32 | cemerick | yeah |
| 11:32 | Raynes | Yeah, that's pretty awesome. |
| 11:32 | Raynes | It's the index on the right that I like the most. |
| 11:33 | Raynes | It isn't intrusive but is very useful if you need to scan through the API. |
| 11:33 | cemerick | make the index a selection panel for larger projects, and it's money |
| 11:33 | Raynes | I'm just not sure it could ever work with the side-by-side layout. |
| 11:34 | cemerick | how do you mean? |
| 11:34 | Raynes | http://raynes.github.com/ororo/ given the side-by-side layout, where would such an outline fit? |
| 11:34 | cemerick | oh |
| 11:35 | cemerick | I'm not attached to that. :-P |
| 11:35 | Raynes | Nor am I. |
| 11:35 | cemerick | I'll probably just start using story. |
| 11:35 | Raynes | Yeah, I'm not really seeing anything wrong with story at this point. |
| 11:35 | cemerick | I'd tinkered with marginalia, but it wasn't useful enough for stuff I wrote. |
| 11:36 | Raynes | I mean, it doesn't rip docstrings, but in what universe would that be useful for a non-side-by-side layout? |
| 11:36 | cemerick | i.e. reference material |
| 11:36 | Raynes | cemerick: I'll write a Leiningen plugin for it in a little while. |
| 11:40 | cemerick | Raynes: Perhaps the outline could go under the TOC? |
| 11:40 | Raynes | cemerick: What really got me thinking was when I did that tentacles blog post and Laurent Petit was completely baffled as to why I had marginalia docs and no autodoc. He pointed out that it wasn't very useful for looking at the API. |
| 11:41 | Raynes | cemerick: That would be excellent, I think. |
| 11:41 | cemerick | It's certainly seems opinionated towards the literate programming thing, which I confess I've not really grokked. |
| 11:41 | cemerick | Raynes: The the side-by-side will work fine. |
| 11:41 | Raynes | I've been doing a form of half-assed literate programming that I really like. |
| 11:41 | Raynes | See my irclj docs for an example. |
| 11:42 | Raynes | http://flatland.org/irclj |
| 11:42 | cemerick | half-assed is the path to salvation. |
| 11:42 | Raynes | I don't think I could ever buy into full-assed literate programming. |
| 11:44 | cemerick | ah, "accordion" is what I was trying to think of… http://jqueryui.com/demos/accordion/ |
| 11:44 | cemerick | s/selection panels/accordion |
| 11:44 | Raynes | Foldable! |
| 11:44 | Raynes | That would be great and would fit in marginalia fine, wouldn't it? |
| 11:45 | Raynes | Only see what you want to see. |
| 11:45 | Raynes | I love you so much, Chas. |
| 11:45 | cemerick | There are tradeoffs. |
| 11:45 | chad_ | Raynes: your comment on full-assed literate programming reminds me of the strange southern french colloquillism "Avoir le cul bordé de nouilles" |
| 11:45 | cemerick | for smaller libs, seeing everything is far preferable and superior |
| 11:46 | cemerick | For libs that have larger namespaces, you need something like an accordion with a scrollable list of vars. |
| 11:46 | Raynes | It seems like a nice compromise. |
| 11:46 | cemerick | …or other namespaces just roll below the frame. |
| 11:47 | cemerick | Both story and marg are javascript-heavy, so a decision could easily be made at load-time as to which is most appropriate. |
| 11:47 | Raynes | Okay, let me know when you've finished implementing all of that. |
| 11:47 | cemerick | What, I'm not ordering off a menu or something? :-P |
| 11:47 | Raynes | ;p |
| 11:52 | Raynes | cemerick: Hah. Story is one big ol' story.clj file. |
| 11:53 | pdk | story.clj has a story all its own to tell |
| 11:53 | cemerick | 700 lines isn't *too* bad |
| 11:54 | pdk | yeah that's about the length of your average java hello world |
| 11:54 | cemerick | mmm, test-free yumminess |
| 11:54 | Raynes | cemerick: To be fair, marginalia's tests weren't passing the last I checked. |
| 11:54 | cemerick | it's a bummer that both have markdown bolted in |
| 11:55 | Raynes | Surely it wouldn't be difficult to have pluggable parsing backends? |
| 11:55 | Raynes | "Dear Marg: Piss off, I like asciidoc." |
| 11:56 | cemerick | no, probably not |
| 11:56 | cemerick | "Quick and dirty dsl for inline css rules, similar to hiccup." Run away, run away! :-P |
| 11:57 | Raynes | Heh |
| 11:57 | Raynes | I'm a fan of hiccup, but not sure how I feel about inline CSS. |
| 11:58 | cemerick | it's wanting for some enlive and gaka. |
| 11:59 | Raynes | Gaka still depends on 1.2.0-master-SNAPSHOT. |
| 11:59 | cemerick | This is unfortunately true. |
| 12:14 | mccraig | cemerick: dyu know what's happening with clojure.core.strint (it's in the core.incubator git repo, but not in the core.incubator 0.1.0 jar on mvnrepository) ? |
| 12:14 | cemerick | it's in 0.1.1-SNAPSHOT |
| 12:15 | cemerick | I think abedra is the lead on incubator, so it's up to him to push a release. You can mail the list about it if you like. |
| 12:16 | mccraig | thx |
| 12:40 | TimMc | Should I bring up the results of ##(list? (list* 1 ())) on the ML? |
| 12:40 | lazybot | ⇒ false |
| 12:41 | technomancy | list? is the worst function in clojure.core, hands down |
| 12:42 | zakwilson | I have never had any desire to call list? that I can recall. |
| 12:42 | TimMc | technomancy: The whole confusion between lists and seqs bothers me. |
| 12:43 | technomancy | lists and seqs is one thing; distinguishing between list and cons is dumb |
| 12:43 | hiredman | cons in clojure is for seqs |
| 12:44 | technomancy | if you care whether something is counted, there's a function for that called counted? |
| 12:44 | TimMc | Well, I like to think there is an abstraction barrier there. |
| 12:45 | TimMc | seqs are a type of coll, `seq` takes you from any coll to a seq, `into` and company take you to various colls. |
| 12:45 | TimMc | But list* returns a seq, not a list. |
| 12:46 | TimMc | technomancy: The use case was someone writing a DSL or whatever the other day. They wanted to distinguish between [] and (). |
| 12:46 | technomancy | TimMc: yeah, that's where I learned to avoid list? too, inside a macro |
| 12:47 | TimMc | &(map list? ['foo (quote foo)]) |
| 12:47 | lazybot | ⇒ (false false) |
| 12:48 | TimMc | Hrm, what was the example? |
| 12:49 | Chousuke | TimMc: code doesn't actually have to be a list so the more robust way is to check for the vector and assume it's a list otherwise :P |
| 12:50 | technomancy | could be a map |
| 12:50 | Chousuke | or check for seq? or something I guess |
| 12:51 | technomancy | anyway, fixing it is a breaking change since the docs state "Returns true if x implements IPersistentList", so IMO it should just be deprecated |
| 12:51 | technomancy | if you really want it, you can type out the whole (instance? clojure.lang.IPersistentList x) call; it's only one more token |
| 12:57 | technomancy | so goooood: http://www.qwantz.com/index.php?comic=2096 |
| 12:59 | zakwilson | Is there a test for whether something is a lazy seq or a non-lazy collection? |
| 13:01 | Raynes | cemerick: Do you actually plan to do anything about the marginalia stuff we were talking about earlier? Just asking because, if not, I'm going to post the logs on my existing issue as food for thought for people who might actually do something at some point (we're probably both too lazy). |
| 13:03 | Raynes | Plus, if I did it... well, we all remember what Try Clojure looked like before LauJensen and apgwoz. |
| 13:04 | cemerick | Raynes: It's in my todo. But, if I could predict when stuff from there would get done, civilization might collapse. |
| 13:05 | Raynes | cemerick: Well, it's on there. That's all that matters. |
| 13:08 | scgilardi | Chousuke: seq? has worked well so far for me as a test for "form" in macro expansions: clojure code rendered in text as "(operator operand1, operand2, ...)" appears always to be lists or conses in the code-as-data seen by macros. |
| 13:09 | drewr | is `lein run` not supposed to work with lein 1.6.2? |
| 13:09 | drewr | I keep getting an exception regarding PersistentList <-> String |
| 13:09 | technomancy | =( |
| 13:10 | Raynes | cemerick: I've got world domination and porn stardom on my TODO list. I'd love to see yours. |
| 13:10 | technomancy | drewr: it worked with 1.6.1? |
| 13:10 | cemerick | Raynes: stop stealing my TODOs |
| 13:10 | drewr | technomancy: no. I updated my 1.x branch because of it too, which is why I'm at 1.6.2 |
| 13:10 | Raynes | Oh man, I'm so sorry. |
| 13:11 | technomancy | drewr: paste the invocation and/or relevant bits of project.clj? |
| 13:11 | cemerick | zakwilson: (instance? clojure.lang.LazySeq x) |
| 13:12 | TimMc | zakwilson: counted? may be more appropriate. |
| 13:12 | drewr | technomancy: is it supposed to be (defproject... :main 'foo.bar)? |
| 13:12 | drewr | maybe I'm missing some syntax in there |
| 13:12 | technomancy | drewr: no need to quote |
| 13:13 | technomancy | drewr: that's a common mistake though; maybe open an issue about getting a better error message? |
| 13:13 | gtrak` | why is there no advantage to lists being able to be transient? |
| 13:14 | drewr | technomancy: or just silently accept a symbol |
| 13:14 | hiredman | technomancy: or check for a seq that starts with quote |
| 13:14 | bartj | folks, is anyone aware of scraping libraries in Clojure ? |
| 13:15 | technomancy | if it were just that place, I'd totally pull a postel's, but I need it to be consistent with every other place namespaces are accepted as symbols. |
| 13:15 | drewr | pedantry will get you nowhere technomancy |
| 13:17 | Raynes | technomancy: Is your init.el file up anywhere? |
| 13:18 | technomancy | Raynes: sure: https://github.com/technomancy/dotfiles |
| 13:18 | Raynes | technomancy: I keep wanting to show everyone my ERC configuration now. |
| 13:19 | technomancy | my own init.el is comprised only of things that aren't generally useful though; I outsource as much of that stuff as I can to the starter kit |
| 13:19 | Raynes | technomancy: https://gist.github.com/1434060 I wrote most of that code all by myself. :> |
| 13:19 | drewr | technomancy: https://github.com/technomancy/leiningen/issues/347 |
| 13:20 | technomancy | Raynes: setq accepts an arbitrary number of symbol/value pairs; you can collapse them into a single call. also read up on eval-after-load. |
| 13:20 | technomancy | drewr: cool; that'll help me remember it for 1.6.3 |
| 13:22 | drewr | ack |
| 13:32 | cemerick | TimMc: ##(counted? (range 5)) |
| 13:32 | lazybot | ⇒ false |
| 13:39 | rickmode | When calling a java method which takes a Integer parameter, I'm having to construct an Integer. Evidently the int primitive returned by the int function is boxed by a Long. Am I missing something? |
| 13:41 | nickmbailey | yes that changed in 1.3 |
| 13:41 | nickmbailey | ints are boxed to longs automatically |
| 13:41 | nickmbailey | you have to use Integer for interop |
| 13:43 | nickmbailey | http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics |
| 13:44 | nickmbailey | boxing shouldn't occur during the interop call though so something like (.javaMethod Object (int 43)) should work |
| 13:44 | TimMc | cemerick: What about it? range is a lazy (chunked) seq. |
| 13:46 | rickmode | nickmbailey: thanks |
| 13:48 | rickmode | well.. the method signature is an Integer, so it has to box somehow. The error when I call with (Foo/bar (int 1)) is java.lang.Long cannot be case to java.lang.Integer. Calling with (Foo/bar (Integer. 1)) works |
| 13:48 | rickmode | Signature is something like "public static void bar(Integer i)" |
| 13:49 | rickmode | obviously this was built before auto-boxing :( |
| 13:49 | pjstadig | (int 1) will create a Long in a boxing context |
| 13:50 | pjstadig | you have to use (Integer. 1) to get a Integer |
| 13:50 | pjstadig | (int 1) is a primitive int cast, which will cause Clojure to box according to it's own boxing rules |
| 13:51 | TimMc | rickmode: Probably wants to allow null. |
| 13:51 | TimMc | technomancy: So... how would *you* define "list"? |
| 13:52 | TimMc | (the Clojure concept, not the fn) |
| 13:53 | technomancy | TimMc: #(.startsWith (pr-str %) "(")) obviously |
| 13:53 | TimMc | >_< |
| 13:53 | technomancy | just kidding, that returns true for clojure.lang.PersistentQueue. |
| 13:54 | technomancy | TimMc: I'd just add (or (instance? clojure.lang.Cons x) ...) |
| 13:55 | TimMc | technomancy: Would you say that the result of cons is also a seq? |
| 13:56 | TimMc | Or that "seq" and "list" are usage patterns, not discoverable from isolated values? |
| 13:57 | nickmbailey | rickmode: that sounds like a bug to me. according to the doc: "It is possible to convert a boxed number into a JVM primitive using one of the following coercion functions: byte, char, int, long, float or double. Be aware, however, that unless the value is an immediate argument to a Java interop call or a Clojure function hinted to match, it is likely to be immediately auto-converted back to a boxed type." |
| 13:57 | technomancy | the result of cons is a list, so it must be a seq |
| 13:58 | nickmbailey | so either the doc is wrong or (Foo/bar (int 1)) should work |
| 13:58 | technomancy | lists are special because they are their own seq |
| 13:58 | hiredman | technomancy: no, the result of cons is a seq |
| 13:58 | hiredman | it is not a list |
| 13:59 | technomancy | hiredman: it's not an instance of clojure.lang.PersistentList, but thinking in terms of classes is not helpful. |
| 13:59 | hiredman | cons is only for adding items to the front of seqs |
| 14:04 | TimMc | hiredman: In case you didn't see context: (list? (list* 1 ())) => false |
| 14:04 | technomancy | yeah, I understand that's how it works under the current implementation of the list? predicate; I just think it's a dumb predicate. |
| 14:05 | technomancy | it's not a helpful distinction to make |
| 14:05 | TimMc | I think *something* is wrong here, but I'm not sure what! |
| 14:05 | TimMc | I'd just like a consistent abstraction. |
| 14:09 | TimMc | I'm fine with seq? and list? both returning true for the same object. |
| 14:12 | hiredman | technomancy: have you looked at the implementation of the cons function? |
| 14:12 | technomancy | you mean in RT.java? |
| 14:13 | hiredman | technomancy: sure |
| 14:14 | TimMc | Presumably you are highlighting the return type? |
| 14:16 | technomancy | ok, what I'm saying is that a list is a thing with a head and a tail; a linked list. a clojure.lang.PersistentList is something more specific. |
| 14:16 | hiredman | technomancy: it is defined as being "add this thing to head of a seq" |
| 14:17 | TimMc | technomancy: seqs and lists *do* have basically the same API, don't they. |
| 14:17 | technomancy | if you want to talk about whether something is a clojure.lang.PersistentList, you should be specific. if someone just says "I have a list", it's reasonable to think they aren't specifically talking about a clojure.lang.PersistentList but a linked list. |
| 14:18 | pjstadig | i've always found this part of clojure muddied IMO |
| 14:21 | TimMc | It definitely increases the cognitive load. |
| 14:21 | hiredman | technomancy: coll? only deals ipcolls and I believe the rest of the predicates are restrictied similarly |
| 14:22 | hiredman | should list? return true for array lists? |
| 14:22 | TimMc | Should lists and seqs even be different things? |
| 14:24 | technomancy | I'm not convinced there should be a list? predicate, but the only two times I've heard of people wanting it, it was to determine if its argument was a piece of code in parens. |
| 14:25 | dnolen | technomancy: there are only a few data structure that guarantee that the rest will be identical? across operations |
| 14:25 | dnolen | cons and list |
| 14:25 | dnolen | this is useful |
| 14:25 | dnolen | an seq doesn't make any such promise because the seq may come from a data structure that doesn't support it. |
| 14:26 | Chousuke | seqs cache the generated values though |
| 14:26 | dnolen | Chousuke: that not the property I'm talking about |
| 14:26 | dnolen | identical?, not = |
| 14:27 | Chousuke | well, I'm not sure why the rest portion couldn't be identical |
| 14:27 | dnolen | Chousuke: it could of course. |
| 14:27 | TimMc | &(let [x [1 2 3]] (identical? (rest x) (rest x))) |
| 14:27 | lazybot | ⇒ false |
| 14:27 | technomancy | not sure how that's useful; IMO the only time identical? is called for is in explanatory texts =) |
| 14:27 | TimMc | happens to not be |
| 14:27 | dnolen | technomancy: just because you haven't used it doesn't mean it's not. core.logic benefits from the guarantee. |
| 14:27 | Chousuke | TimMc: that example is wrong |
| 14:28 | Chousuke | TimMc: you're calling rest on two different seqs |
| 14:28 | technomancy | isn't the whole point of egal to not have to think in terms of identical? |
| 14:28 | Chousuke | on the same vector. |
| 14:28 | amalloy | &(let [x [1 2 3], s (seq x)] (identical? (rest s) (rest s))) |
| 14:28 | lazybot | ⇒ false |
| 14:28 | dnolen | technomancy: performance, you don't want to traverse to determine equality - you know what you're doing. |
| 14:28 | TimMc | Chousuke: Oops, you're right. The point dnolen was making was more subtle than I thought. |
| 14:29 | technomancy | dnolen: ok, but I'd argue if you care about that level of perf you're well into breaking-through-abstractions territory and you're probably also concerned about the difference between array-map and hash-map, etc. |
| 14:29 | Chousuke | &(let [x [1 2 3], s (seq x)] (identical? (next s) (next s))) |
| 14:29 | lazybot | ⇒ false |
| 14:29 | technomancy | you can write your own predicates |
| 14:31 | dnolen | technomancy: there's seems to be a bit functional literature out there that leverages the identical? guarantee offered by cons / list. |
| 14:31 | dnolen | so it's worth preserving in Clojure IMO. |
| 14:40 | technomancy | yeah, definitely makes sense to preserve that guarantee. not sure how that plays into what defines a list though. |
| 14:41 | hiredman | (defn cons [x y] (reify clojure.lang.ISeq (first [_] x) (next [_] y))) |
| 15:20 | patchwork | hey all, where did dissoc-in go in 1.3? |
| 15:20 | patchwork | can't find any docs on it |
| 15:20 | patchwork | they all say it is in clojure.contrib.core |
| 15:21 | patchwork | even better, how could I discover this? Is there a handy migration list for 1.3? |
| 15:23 | cemerick | patchwork: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 15:31 | TimMc | patchwork: I think dissoc-in was removed in favor of using update-in with dissoc. |
| 15:32 | patchwork | TimMc: that is what I needed to know, thank you! |
| 16:00 | flazz | i'm using clojure.tools.logger and my messages all contain sun.reflect.NativeMethodAccessorImpl as the namespace, how do i change this? |
| 16:14 | TimMc | flazz: The answer probably depends on which logger you are using. |
| 16:14 | flazz | jul |
| 16:21 | TimMc | ? |
| 16:21 | TimMc | Is that j.u.logging or something? |
| 16:23 | amalloy | seventh month of the year |
| 16:32 | amalloy | hm. this makes sense but kinda makes me sad: if your function foo returns a function f as (comp g h), and f is later called and blows up, foo doesn't show up in the stacktrace at all. does anyone have advice for figuring this out? in this case i knew foo was the culprit but if i didn't i'm not sure how i would track down which instance of comp was causing the problem |
| 16:34 | hiredman | amalloy: I dunno how you could change that in an acceptable way |
| 16:35 | hiredman | the functions a generated at compile time and their class names reflect lexical scope, but you want the stacktrace to reflect dynamic scope, which is not known and compile time |
| 16:36 | hiredman | maybe if comp was inline-able, but that is not a general solution |
| 16:37 | amalloy | yeah, i don't really see a viable solution either |
| 16:38 | amalloy | you couldn't get it into the java stacktraces, but maybe you could put metadata on the returned function somehow, to get some crude diagnostics? even that seems pretty challenging |
| 16:39 | hiredman | the best solution to errors is always: know what you are doing and don't make errors |
| 16:41 | technomancy | I find that internally-named fns are pretty handy for debugging |
| 16:41 | technomancy | (fn does-a-thing [x] [...]) |
| 16:41 | flazz | TimMc: yep java.utls.logging, sorry |
| 16:43 | hiredman | technomancy: but if you create the fn with comp you don't have that |
| 16:43 | technomancy | hiredman: yeah, I don't think there's a good point-free answer for that |
| 16:45 | TimMc | flazz: If that's anything like log4j, you'll put some sort of properties file into the classpath with the configuration details you need. |
| 16:45 | TimMc | amalloy: Solution: Make comp a macro. :-P |
| 16:46 | TimMc | (scratch that, it doesn't make enough sense to be funny) |
| 16:46 | amalloy | right, i wound up changing it to #(g (h %)) so that i could confirm it was inside foo |
| 16:47 | TimMc | amalloy: The generated classname includes foo? |
| 16:47 | amalloy | of course. foo$fn__2349 or something |
| 16:48 | amalloy | &((fn foo [] #(inc 1))) |
| 16:48 | lazybot | ⇒ #<sandbox12996$eval16802$foo__16803$fn__16804 sandbox12996$eval16802$foo__16803$fn__16804@e3313a> |
| 16:54 | TimMc | That is suprisingly useful and obvious. |
| 16:56 | technomancy | weavejester: heya |
| 16:57 | weavejester | technomancy: Hey there |
| 16:58 | technomancy | how goes the hacking on ragtime? |
| 16:58 | technomancy | did that ordering trick work out? |
| 16:58 | weavejester | Perfect :) |
| 16:58 | technomancy | sweet |
| 16:59 | weavejester | I also changed the functions from 0-arg to 1-arg. |
| 16:59 | technomancy | thinking of trying out on clojars |
| 16:59 | weavejester | With the one argument being the database. |
| 16:59 | jcromartie | good call |
| 17:00 | weavejester | So (migrate db [foo]) will run ((:up foo) db) |
| 17:00 | technomancy | looks like it still needs an adapter for sql; maybe that could just be yoinked from migratus? |
| 17:00 | weavejester | Yeah, I'm working on a ragtime.sql. I haven't got very far though, so grabbing one from migratus is probably a good idea. |
| 17:01 | technomancy | curious: are you using this for work? |
| 17:01 | weavejester | I was also looking into maybe grabbing the one from Lobos, as I'm using that librart anyway. |
| 17:01 | technomancy | https://github.com/weavejester/ragtime/graphs/punch_card <= guessing not =) |
| 17:01 | weavejester | No, currently work is a Ruby shop |
| 17:01 | weavejester | No Clojure there yet. |
| 17:01 | technomancy | bummer |
| 17:02 | weavejester | Yeah, but on the other hand, it gives me a window into what's happening in Rails webdev |
| 17:02 | weavejester | My current plan is to make the database connection map a record |
| 17:03 | weavejester | So then I can add the "Migratable" protocol to it that allows me to store migrations. |
| 17:03 | weavejester | I'm not 100% sure about it, but it's the best solution I've come up with so far... |
| 17:03 | technomancy | hmm... I just refactored c.j.jdbc so that you can pass a database URL string instead of the connection map |
| 17:04 | technomancy | I guess you could extend it to string and URL and parse it there |
| 17:04 | weavejester | technomancy: I was thinking about writing a library for that :) |
| 17:04 | technomancy | that's your catch-phrase, innit? |
| 17:04 | weavejester | Haha! I'm a fan of many small libraries |
| 17:05 | weavejester | Apparently the empirical evidence suggests bugs are closely related to the number of lines of code. |
| 17:05 | weavejester | So less code = less bugs on average |
| 17:05 | technomancy | yeah, as long as the abstractions are rock-solid |
| 17:05 | weavejester | Yeah. |
| 17:05 | technomancy | because the other side of the coin is that more libraries means more integration points |
| 17:06 | technomancy | but in general I agree |
| 17:06 | weavejester | So I need the "Migratable" protocol so that I can store migrations without mandating a specific type of database. |
| 17:06 | weavejester | I mean, that makes sense, right? |
| 17:06 | technomancy | yeah, I think so. |
| 17:07 | weavejester | So (migrate db migration-list) |
| 17:07 | technomancy | it would be nice if you could pass the exact same config to ragtime and c.j.jdbc, but that might just be unrealistic |
| 17:07 | weavejester | Or (migrate-ns db & namespaces) |
| 17:07 | technomancy | nice |
| 17:07 | weavejester | Originally I was going to have it execute migrations like ((:up migration)) |
| 17:07 | weavejester | But now I've changed it to ((:up migration) db) |
| 17:08 | weavejester | Because it seems like a good idea to pass the database connection info through the migrate function |
| 17:08 | weavejester | Essentially saying "migrate this database with these migrations" |
| 17:09 | weavejester | I guess I could just use a wrapper. |
| 17:09 | technomancy | I think taking an arg makes sense |
| 17:09 | weavejester | (migrate #SqlDatabase{:url "..."} ...) |
| 17:09 | technomancy | but we'll probably have to flesh out a few adapters to really get a feel for what works |
| 17:09 | weavejester | Yeah |
| 17:10 | weavejester | Or maybe: (migrate-ns (sql-database db-url) 'my.app.migrations) |
| 17:12 | weavejester | One of these days I'll run out of libraries to build, and then I'll actually be able to make an application |
| 17:13 | technomancy | do you want a hand with the sql adapter? |
| 17:14 | weavejester | technomancy: Sure |
| 17:14 | weavejester | I rarely turn away a helping hand :) |
| 17:15 | technomancy | check your /msgs |
| 18:08 | accel | is there a godo book / chapter of a book / tutorial on Swing + Clojure? |
| 18:09 | accel | What is a godo book / chapter of a book / tutorial on Swing + Clojure? (I don't want a yes/no answer, I want a reference :-) ). |
| 18:20 | Raynes | Tutorials on swing + Clojure are fairly lacking, though I'll be covering it in my book. That doesn't help you much now. |
| 18:23 | Wild_Cat | Raynes: when is said book supposed to come out? |
| 18:23 | Raynes | I wish I knew. |
| 18:23 | Wild_Cat | (also, I get the feeling that it'd be pretty interesting to model the UI as an agent) |
| 18:24 | Raynes | I'll be covering Seesaw in the book. |
| 18:24 | Raynes | http://github.com/daveray/seesaw |
| 18:28 | gtrak` | Wild_Cat, why agent over atom? |
| 18:28 | gtrak` | or ref, I guess |
| 18:28 | Wild_Cat | gtrak`: because I'm envisioning every event as a message it could/should send to other agents (the actual program logic) |
| 18:29 | Wild_Cat | also, because I'm a Clojure noob and it's likely my understanding of its concurrency and synchronization primitives is sketchy. |
| 18:30 | gtrak` | hmm, well the downside of an agent is when you actually want stuff to happen synchronously |
| 18:30 | gtrak` | I guess if the queue is small, it's no big deal |
| 18:31 | Wild_Cat | yeah, there's the potential issue of the UI lagging way behind the user's commands |
| 18:31 | Wild_Cat | which tends to happen when you accept too many of those, usually as a side effect of event handlers returning immediately |
| 18:32 | gtrak` | there's really no downside of a single rendering thread, is there? |
| 18:33 | gtrak` | but I know that in swing it's easy to do the wrong thing, maybe seesaw makes that better? |
| 18:34 | Wild_Cat | as long as rendering is fast or easy to break down in steps that are and return quickly, no downside. The problems start creeping in when rendering is neither fast nor broken down in small steps. |
| 18:34 | gtrak` | Wild_Cat, I've done programming in adobe flex, you only have a single thread there, and event queues, it's pretty flexible though unless you have long-running work and need to interleave it between frame-renderings |
| 18:34 | Wild_Cat | at which point your UI hangs while your logic is processed, a very common issue in Swing programs |
| 18:34 | amalloy | swing tells you not to interact with gui elements in anything but the event dispatch thread |
| 18:34 | Wild_Cat | gtrak`: yeah, it's pretty much exactly that problem ;) |
| 18:34 | Wild_Cat | (to be fair, you get it in most UI toolkits) |
| 18:36 | gtrak` | the data-binding was super-nice though, basically any time a property changes, an event bubbles up and updates everything that it needs to update |
| 18:36 | Wild_Cat | ah, nice. |
| 18:36 | gtrak` | like this: <mx:Binding source="source.text" destination="destination.text" /> |
| 18:36 | gtrak` | or <mx:TextInput id="destination" text="{source.text}" /> |
| 18:37 | Wild_Cat | that's another thing Swing sorely lacks: a declarative UI representation format. |
| 18:38 | Wild_Cat | ...or anything that makes working with a WYSIWYG UI designer something other than a massive kludge that autogenerates megabytes of horrible Java code |
| 19:16 | accel | Raynes: perhaps I am asking the wrong question. |
| 19:16 | accel | What are the currently well used methods for doing GUI in Clojure? |
| 19:17 | accel | To me, the important bits are: I need to code in Clojure. I need to have a GUI. |
| 19:17 | accel | Swing is replacable. |
| 19:18 | accel | Also, did anyone ever port the GUI that common lisp systems had to clojure? |
| 19:18 | cemerick | Swing and SWT are the only games in town, really. |
| 19:19 | cemerick | plus using an embedded webkit view via SWT and using a web UI on the desktop :-P |
| 19:19 | cemerick | There was a tasty Clojure swing wrapper that just came out that looked very promising… |
| 19:20 | accel | IIRC, common lisp had a very interesting GUI toolkit: clim, I thin it was called. |
| 19:20 | accel | Is there no port of it to clojure? |
| 19:22 | cemerick | Surely not. |
| 19:22 | TimMc | cemerick: Yeah, the next time I can get away with it, I'm writing a web GUI. |
| 19:22 | accel | TimMc: why? |
| 19:22 | cemerick | If clim is your benchmark, then the framework doesn't matter that much, it's the construction of the API you care about. |
| 19:22 | accel | Why is Web GUI easier than Java GUI? |
| 19:23 | cemerick | Declarative layout is nifty. |
| 19:23 | accel | cemerick: sure; I care more about the API than "framework" |
| 19:23 | TimMc | accel: It's not that it's easier (although it often is), it's that you can meet more of the user's interface expectations. |
| 19:24 | TimMc | Cross-platform GUIs are often awkward for the user. |
| 19:24 | TimMc | They look wrong and feel wrong on *every* platform. |
| 19:24 | accel | lol |
| 19:24 | accel | I believe this is called *fairness* |
| 19:24 | TimMc | haha |
| 19:24 | TimMc | Something declarative that got compiled to each platform's widgets would *rock*. |
| 19:25 | duck1123 | but they look wrong in different ways depending on the OS |
| 19:25 | duck1123 | TimMc: you mean, HTML? |
| 19:25 | cemerick | accel: try https://github.com/stathissideris/clarity or https://github.com/daveray/seesaw |
| 19:26 | accel | ce |
| 19:26 | accel | cemerick: going to try clarity just because I like the name better |
| 19:27 | TimMc | duck1123: Just about. |
| 19:27 | zerokarmaleft | technomancy: does emacs-starter-kit override settings in init.el for cc-mode somewhere? |
| 19:27 | TimMc | It could totally be done. |
| 19:27 | accel | what if, we took HTML |
| 19:27 | accel | then we made it scriptable |
| 19:27 | accel | with a scripting language |
| 19:27 | TimMc | heh |
| 19:27 | technomancy | zerokarmaleft: version 1 or 2? |
| 19:27 | accel | the scripting langauge would be cross platform, like Java |
| 19:27 | duck1123 | hold the phone |
| 19:28 | accel | but it would be for Scripting purposes |
| 19:28 | zerokarmaleft | technomancy: 2 |
| 19:28 | technomancy | zerokarmaleft: 2 doesn't add any bindings outside the starter-kit-bindings module, but I don't know if it overrides anything in cc-mode because I've never used it. |
| 19:29 | accel | Sadly, I think the approach I want to take |
| 19:29 | accel | is to suffer and deal with Swing directly so I can build my own abstractions. |
| 19:29 | accel | What is the most hardcore way to learn Swing? |
| 19:30 | duck1123 | accel: flagelate yourself for every bug |
| 19:30 | accel | No no, I don't want a Darwin award. |
| 19:30 | accel | I'm looking for the K&R equivalent, i.e. |
| 19:30 | accel | "The Swing GUI Library" |
| 19:30 | accel | [2nd edition] |
| 19:32 | zerokarmaleft | technomancy: ok...i hadn't installed bindings yet anyway |
| 19:35 | zerokarmaleft | maybe cc-mode has changed in 24, i'll check that |
| 19:53 | seancorfield | boy, i've had one of those days where i just love clojure! |
| 19:54 | seancorfield | we have a custom search engine that returns a block of results with metadata on each call and now, thru clojure, i have a single search call that returns three lazy sequences that call the search engine as needed to get results as we page thru results! |
| 19:58 | Raynes | seancorfield: I'm going to be doing something similar for paging in tentacles. |
| 20:06 | yayitswei | how would I group items in a list based on a cumulative function? e.g. split when sum is greater than 10: (9 1 2 5 1 8) -> ((9 1) (2 5 1) (8)) |
| 20:09 | duck1123 | yayitswei: IIRC there's a reductions fn in combinatorics that returns each stage of a reduction, that might get you started |
| 20:11 | yayitswei | ah quite useful, ty |
| 20:12 | duck1123 | not quite sure how you'll make it work, but it should help |
| 20:13 | brehaut | ,#((map vector % (reductions + 0 %)) [1 2 5 3 4]) |
| 20:13 | clojurebot | #<sandbox$eval28$fn__29 sandbox$eval28$fn__29@25dd02> |
| 20:13 | brehaut | crap |
| 20:13 | brehaut | ,(#(map vector % (reductions + 0 %)) [1 2 5 3 4]) |
| 20:13 | clojurebot | ([1 0] [2 1] [5 3] [3 8] [4 11]) |
| 20:14 | brehaut | nah thats ugly |
| 20:22 | amalloy | this feels like something i wrote recently, but i can't remember what it actually was |
| 20:24 | yayitswei | here's what i have so far: (reductions #(if (<= (+ %1 %2) 10) (+ %1 %2) %2) '(9 1 2 5 1 8)) |
| 20:26 | brehaut | oh. its not a foreclojure question is it? |
| 20:27 | Raynes | amalloy has returned?!? |
| 20:27 | yayitswei | nope, at least not afaik |
| 20:28 | amalloy | nah, i though wrote it as a response to something on the google group. but i can't find it |
| 20:28 | amalloy | my basic premise was "it seems like you should be able to do this with reductions and split-with or something, but it was easier to just write with lazy-seq directly" |
| 20:30 | rickmode | I'm doing a remote debugging via swank-clojure, but when I tried (swank.core/break) I get IllegalStateException: Attempting to call unbound fn: #'swank.core.connection/*current-connection* |
| 20:32 | rickmode | I did a C-c c on my (ns ..) line that added :require swank.core and on the fn that has (swank.core/break). And oddly, if I require swank.core.connection, I can see *current-connection* in my remote REPL. |
| 20:33 | drivera | .exit |
| 20:35 | amalloy | yayitswei: https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L191 is maybe a little relevant/useful? |
| 20:40 | yayitswei | thanks amalloy, i'm finishing up my split-with version and i'll take a look in a sec |
| 20:44 | amalloy | VICTORY. it was http://groups.google.com/group/clojure/browse_thread/thread/fc08587280d2244e/c266706ed52c8d2?q=#0c266706ed52c8d2 - someone wanted to group a bunch of strings such that each partition had a maximum size <= N |
| 20:58 | ihodes | anyone hiring Clojure devs about to graduate from school? :) |
| 21:21 | yayitswei | nice.. thanks amalloy |
| 21:53 | brweber2 | how do I make my protocol extend Map? |
| 21:54 | brehaut | (doc extend-protocol) |
| 21:55 | clojurebot | "([p & specs]); Useful when you want to provide several implementations of the same protocol all at once. Takes a single protocol and the implementation of that protocol for one or more types. Expands into calls to extend-type: (extend-protocol Protocol AType (foo [x] ...) (bar [x y] ...) BType (foo [x] ...) (bar [x y] ...) AClass (foo [x] ...) (bar [x y] ...) nil (foo [x] ...) (bar [x y] ...)) expands into: (do (clojure.c |
| 21:55 | brehaut | ,(supers (class {})) |
| 21:55 | clojurebot | #{clojure.lang.IPersistentCollection clojure.lang.IPersistentMap clojure.lang.Counted clojure.lang.IMeta clojure.lang.AFn ...} |
| 21:56 | brehaut | brweber2: clojure.lang.IPersistentMap is the interface you want to implement the protocol for. you can either do it in the protocol definition, or with extend-protocol. |
| 21:56 | brweber2 | brehaut: thanks |
| 21:56 | brehaut | brweber2: i am under the impression that if you define it in the protocol definition, then it will be a bit faster than if its done later |
| 21:57 | brweber2 | brehaut: perfect. I forgot about supers for checking the hierarchy |
| 22:05 | amalloy | brehaut: you can't include any implementation in the definition of a protocol; you're probably thinking about inlining protocol implementations when defining a type, but your advice doesn't make sense in that context: you don't control the creation of the IPersistentMap class so there's nowhere to inline |
| 22:05 | brehaut | amalloy: aha yes of course i am |
| 22:22 | tmciver | Anyone using CDT from a repl? I tried following http://georgejahad.com/clojure/cdt.html but when I (use 'com.georgejahad.cdt) I get they FileNotFoundException. |
| 22:33 | seancorfield | tmciver: i think the namespaces have changed recently? |
| 22:33 | seancorfield | i got this working: http://georgejahad.com/clojure/swank-cdt.html |
| 22:35 | tmciver | seancorfield: I was just looking at that. I wanted to see if I could get *pure* CDT working w/o swank. I guess I'll just move on to swank-cdt. |
| 22:42 | jcrossley3 | why was clojure.java.io/delete-file-recursively removed from 1.3? |
| 22:49 | erujolc | using the clojure 1.3 repl (clj) from a terminal emulator in linux it doesnt behave very natively e.g. if i type (def x 1) <Enter> and then on the next line the up arrow instead of showing last command shows the escape of up arrow |
| 22:49 | amalloy | $google rlwrap |
| 22:49 | lazybot | [rlwrap - utopia.knoware.nl] http://utopia.knoware.nl/~hlub/rlwrap/ |
| 22:49 | amalloy | erujolc: ^ |
| 22:50 | Raynes | Leiningen handles that for you. |
| 22:50 | amalloy | though really, don't use clj at all; install lein and it will make a repl with readline |
| 22:50 | Raynes | That. |
| 22:51 | Raynes | https://github.com/technomancy/leiningen |
| 22:51 | erujolc | thanks |
| 22:51 | erujolc | lein repl works perfectly |
| 22:52 | Raynes | 'clj' is not an official Clojure thing. It's just a script that your package manager probably installed to start up a REPL. You still have to deal with handling the classpath once you've began a project and start having dependencies. Leiningen does that too. |
| 22:52 | erujolc | thanks. yes i believe clj was installed via pacman (archlinux) |
| 23:02 | erujolc | OT: techie podcasts worth subscribing to? |
| 23:08 | devn | What's the channel for chicken scheme? |
| 23:15 | Raynes | devn: Wild guess, but I'd assume it to be #bawwwwwwwwk. |