#clojure log - Feb 24 2012

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

0:01 devn: &(symbol "_-*!?.omg.?!*-_")

0:01 lazybot: ⇒ _-*!?.omg.?!*-_

0:01 devn: muhoo: that's not a real function name, that is a replacement made by the editor

0:02 muhoo: the overtone emacs configuration replaces the "fn" in (fn [x] (+ 1 x)) with a lambda

0:02 it still says fn underneath

0:02 muhoo: ah, thanks

0:02 devn: you *can* use unicode, but it is not common at all to do that

0:03 in fact, i've never seen anyone do that outside of demonstrating is *can* be done

0:03 so if you see that sort of thing, it likely is just an editor thing

0:03 muhoo: &(let [_-*!?.omg.?!*-_ "buuaahhaha"] )

0:03 lazybot: java.lang.ClassFormatError: Illegal field name "___STAR__BANG__QMARK_.omg._QMARK__BANG__STAR___" in class sandbox16652$eval22430

0:04 muhoo: java no likey

0:04 arohner: &(let [_-*!?omg?!*-_ "buuaahhaha"] )

0:04 lazybot: ⇒ nil

0:04 arohner: it didn't like the periods

0:04 muhoo: ah, namespace delimiters

0:05 bbloom: …soo type hinting + generics = simply ignore the generics?

0:05 it seems that clojure.reflect will return symbols with <> at the end of the name… which doesnt seem to hint right

0:07 devn: bbloom: example?

0:08 arohner: bbloom: pretty much. generics are only at the java "user" level. The JVM doesn't know or care about generics

0:08 devn: arohner: you're right, (symbol ..) is not the ultimate test

0:08 bbloom: devn: clojure.reflect/type-reflect returns symbols with <> in them

0:08 arohner: or foo(String…)

0:08 bbloom: but then i get an error can't find SomeType<> when trying to use that symbol in type hints

0:08 devn: bbloom: i was thinking of a code example

0:09 bbloom: yeah, working on one

0:09 taapa: New to both Clojure and Java. Java is vast. What is a good intro to Java resource for learning enough for Clojure?

0:09 devn: taapa: "enough" is always relative to your goals. :)

0:10 bbloom: devn: hmmm maybe i'm mistaken…. this works:

0:10 blah.interop=> (reify Iterable (^:java.lang.Iterator<> iterator [this] nil))

0:10 #<interop$eval1744$reify__1745 blah.interop$eval1744$reify__1745@5d5cd49f>

0:10 i'll try to figure out what the heck i'm doing wrong :-)

0:10 devn: taapa: google as you go. or read a book. your choice.

0:11 bbloom: i think ^: is old style, but i dont use hinting much

0:11 i think you want ^java.lang.Iterator

0:11 bbloom: devn: what's new style?

0:11 i need the hinting to reify an interface that differentiates overloads by argument type

0:11 devn: bbloom: i might have this completely wrong.

0:12 arohner: back me up? :)

0:13 arohner: yes, in 1.3, ^Iterator

0:13 * devn wipes sweat

0:14 bbloom: ok i figured out what's up here… take a look at this

0:14 (reify Iterable (^{:tag java.util.Iterator} iterator [this] nil))

0:14 #<interop$eval1784$reify__1785 blah.interop$eval1784$reify__1785@405084c6>

0:14 ^^ works

0:14 but...

0:14 (reify Iterable (^{:tag java.util.Iterator<>} iterator [this] nil))

0:14 CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: java.util.Iterator<>, compiling:(NO_SOURCE_PATH:1325)

0:14 notice the <>

0:14 the output of clojure.reflect isn't directly usable for type hinting… you need to strip the <>

0:15 seems like the <> should just be stripped automatically

0:16 devn: type hints remove reflection, no?

0:16 muhoo: wow, aleph is unhappy https://refheap.com/paste/815

0:17 bbloom: right, but i'm doing reflection at macro expansion time, so i dont have to do it at run time

0:17 taapa: Just curious (class 8) => java.lang.Integer. Why don't Clojure implements its own clojure.lang.Integer? Soory if it is naive qn, its my third day learning Clojure

0:17 devn: taapa: why would/should it implement its own?

0:19 muhoo: you're using clojure 1.3 and the version of aleph you're using is 1.2(.1)

0:19 1.3 throws those warnings for "earmuffed" vars

0:19 taapa: devn: maybe less confusion to noob and to someone not from Java? since its such basic type. Not sure maybe it is how clojure is, expect it to be less dependent on host platform especially for core type.

0:19 bbloom: devn: this helps:

0:19 (defn- hint [obj tag]

0:19 (let [tag (-> tag .toString (.replace "<>" "") symbol)]

0:19 (with-meta obj {:tag tag}));)

0:20 arohner: taapa: Clojure sees being able to interop with JVM libraries as a strength

0:20 devn: taapa: it is a symbiotic relationship

0:20 taapa: the JVM is a mature platform

0:20 gtrak: devn, I managed to make it work by keeping a refcount of pressed notes, though I'm pretty sure kill isn't the right way to go, it pops at the end

0:20 devn: it's core types are used as an advantage

0:21 gtrak: :\ sorry man, you really should ask on the overtone list

0:21 id like to know the right answer as well

0:21 gtrak: https://gist.github.com/1897956

0:21 take a look, for posterity anyway

0:22 devn: not a bad idea i suppose, but maybe more heavy handed than required gtrak

0:22 gtrak: it seems like having a ref or atom of layers would be handy

0:22 gtrak: yea

0:22 bbloom: updated version of my reify-delegate macro with type hinting: https://refheap.com/paste/816 — I'll see if I can file a bug regarding the <> mismatch

0:22 devn: but it also seems sort of like whipped cream on a nice cup of coffee, too much :)

0:23 gtrak: this works if what you want is a note to play only once

0:23 i think in my case that's right

0:23 devn: gtrak: perhaps you just need to add a duration when playing?

0:23 gtrak: i believe there are insts which have a :dur arg

0:24 bbloom: sorry i couldnt have been of more help

0:24 gtrak: devn, it's going to be a little weird, I'm trying to make it act like an accordion

0:24 so notes don't really stand on their own

0:24 technomancy: devn: serializable-fn is primarily to allow functions to be first-class in a cluster of workers

0:24 bbloom: devn: was still helpful :-) my hint function solves the problem

0:24 devn: gtrak: matter of fact i've seen someone else do an accordion :)

0:24 muhoo: hmm, went with the latest aleph snapshot, and got these https://refheap.com/paste/817

0:24 bbloom: will file a bug for sake of others trying to use clojure.reflect to generate reify forms

0:25 gtrak: devn, probably me :-)

0:25 technomancy: like for https://github.com/technomancy/die-roboter

0:25 devn: technomancy: that makes sense. sorry for prodding

0:25 just wanted to eek out a use case, 'cause i couldn't see one

0:25 technomancy: fair enough; it doesn't make much sense in a non-distributed setting.

0:26 devn: now i wanna use it

0:26 avout + serializable-fn

0:26 technomancy: dude

0:26 die-roboter is like 100LOC

0:27 just sayin

0:27 devn: technomancy: plus it has the word tachyon in it, and german in the README

0:28 consider me sold :)

0:28 technomancy: it's got it's own theme song!

0:28 * devn plays gtrak's overtone accordion

0:28 gtrak: devn, github.com/gtrak/clj-accordion

0:28 devn: yeah! i've played with this!

0:29 gtrak: it's like a week old

0:29 devn: i know :)

0:29 gtrak: ha, lol, you played with it alread?

0:29 devn: i like playing with overtone, i like browsing insts people have made

0:29 yeah :)

0:29 gtrak: I have a pull request on overtone/grid right now, you'll need my forked version to try it out

0:29 devn: there's an overtone-toys repo ( i think that's the name )

0:29 technomancy: johnmn3: you should set -Xmx256m for both JVM_OPTS and LEIN_JVM_OPTS I think

0:29 gtrak: assuming you have a launchpad

0:29 technomancy: adjust the numbers as appropriate

0:29 devn: it has a really cool binaural inst

0:30 johnmn3: technomancy: so put that in my project.clj?

0:30 devn: i have to bed all, happy clojuring, and may the power of hash array mapped tries be with you

0:30 to *go to* bed

0:31 g'night

0:31 johnmn3: oh, put in my environment variables

0:35 technomancy: didn't work

0:35 trying with trampoline

0:38 muhoo: so what's the clojureish way to find out what functions are available for a particular peice of data?

0:39 in oop, it's easy, the object has methods, etc. but for a clojure thing, how do i find out what functions are valid to do upon it?

0:39 * muhoo has a hunch it has something to do with protocols

0:41 amalloy: step 1, use a language with static typing?

0:42 given some function x, you can't possibly know what types it accepts, because it doesn't say so anywhere

0:46 johnmn3: functions should be as datastructure-agnostic as possible, right?

0:46 callen: johnmn3: possible, practical, etc.

0:51 johnmn3: ,(#(if (= :rare-data %) "usually nil" nil) :common-data)

0:51 clojurebot: nil

0:56 Raynes: amalloy: 1) write a function 2) run function against every single data type possible 3) ????????? 4) profit!

1:02 johnmn3: any selenium/clj-webdriver gurus out there?

1:06 bbloom: is there a way to get the . form to play nice with apply?

1:08 johnmn3: if the driver clicks and opens a new window and then the user closes that window, the driver is hosed

1:11 and then I can't get a way back into the running browser

1:12 bbloom: &(apply .charAt "asdf" [2])

1:12 lazybot: java.lang.RuntimeException: Unable to resolve symbol: .charAt in this context

1:12 bbloom: any way to make that work? preferably with the isolated dot form?

1:12 johnmn3: methods aren't functions

1:12 callen: &(apply (. charAt "asdf") [2])

1:12 lazybot: java.lang.RuntimeException: Unable to resolve symbol: charAt in this context

1:12 shaolynn: Is anyone here familiar with aleph? What's the best way to serve a policy file for web sockets?

1:12 johnmn3: ,(memf .charAt)

1:13 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: memf in this context, compiling:(NO_SOURCE_PATH:0)>

1:13 bbloom: aaaah memf

1:13 ,(docmf .charAt)

1:13 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: docmf in this context, compiling:(NO_SOURCE_PATH:0)>

1:13 bbloom: blah

1:13 ,(doc memfn)

1:13 clojurebot: "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."

1:17 bbloom: hmmm does memfn play nice with varargs?

1:18 look at the impl doesn't suggest it would....

1:19 johnmn3: might as well wrap it in a function at that point

1:19 memfn is kinda like comp

1:19 bbloom: well if i knew how to write the wrapper function, i'd have just written that inline :-)

1:20 johnmn3: #(.charAt %)

1:20 bbloom: johnmn3: charAt was just a simplified example

1:21 i'm trying to reify a varargs method

1:21 johnmn3: what were you trying to do with [2]?

1:25 bbloom: johnmn3: I am trying to call a varargs java method against a sequence

1:25 but i cant even get it to work against a non-vararg method

1:25 &(apply #(.charAt "asdf" %) [2])

1:25 lazybot: ⇒ \d

1:25 bbloom: that seems to work… but what about varargs?

1:27 hmmm or are varargs not even really a thing?

1:27 like is it just compiler knowledge & it's actually just an array?

1:28 Apage43: bbloom: yes, according to java's docs

1:28 "It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process."

1:28 bbloom: Apage43: ah. thanks. link?

1:29 Apage43: http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html

1:29 bbloom: ah ok thanks

1:32 muhoo: what's the function in clojure to render a number in any base?

1:33 i.e. in binary, hex, etc, there's one function that takes the number and base, and displays it

1:33 bbloom: ,(doc *print-base*)

1:33 clojurebot: Excuse me?

1:33 muhoo: wasn't that one

1:33 bbloom: &(doc *print-base*)

1:33 lazybot: java.lang.RuntimeException: Unable to resolve var: *print-base* in this context

1:33 bbloom: blah.

1:33 muhoo: it was a function, like (foo 295 16)

1:34 bbloom: grepping for *print-base* produces some results…. um… let's see

1:34 muhoo: it was in clojure.contrib.math IIRC

1:35 bbloom: well you can simply bind *print-base*

1:35 in pretty print

1:35 pprint

1:36 (use '[clojure.pprint])

1:36 muhoo: well i don't want to change the base for every number, just fo rone

1:36 bbloom: (with-out-str (binding [*print-base* 16] (write 100)))

1:36 "64"

1:36 muhoo: oh i see

1:36 still, there was a simpler way, my memory fails me though

1:37 bbloom: let me know if you find it :-)

1:43 shaolynn: What's the best way to examine libraries from the REPL - for example: how can I list the methods of a library?

1:46 bbloom: &(doc dir)

1:46 lazybot: java.lang.RuntimeException: Unable to resolve var: dir in this context

1:46 bbloom: hmm.

1:46 ,(doc dir)

1:46 user=> (doc dir)

1:46 -------------------------

1:46 clojure.repl/dir

1:46 ([nsname])

1:46 Macro

1:46 Prints a sorted directory of public vars in a namespace

1:46 nil

1:48 clojurebot: "([nsname]); Prints a sorted directory of public vars in a namespace"

1:48 bbloom: heh… clojurebot was a little slow on that 1 :-)

1:50 shaolynn: bbloom: awesome, thx!

1:56 gfredericks: does this sort of thing ring a bell to anyone? Don't know how to create ISeq from: clojure.lang.Var$Unbound

2:00 muhoo: methinks it was called 'rad' or 'radice'

2:01 bbloom: gfredericks: you've got something that was (def foo) without an init value

2:01 and you're trying to dereference it

2:07 muhoo: bbloom: (Integer/toHexString 42)

2:07 &(Integer/toHexString 42)

2:07 lazybot: ⇒ "2a"

2:07 muhoo: &(Integer/toBinaryString 42)

2:07 lazybot: ⇒ "101010"

2:08 bbloom: muhoo: heh, isn't that Java's? Cheating ;-)

2:08 muhoo: it works, and it doesn't wreck my fingers or my brain, so i'm happy

2:08 bbloom: indeed

2:28 ibdknox|away: when you're doing deftype and you are implementing a protocol it doesn't throw if you don't implement all the methods?

2:35 nuclearsandwich: ibdknox|away: first time playing with Noir in earnest. Does it still support named routes?

2:35 ibdknox|away: yeah

2:36 nuclearsandwich: I have `(defpage auth-callback "/auth/callback" {code :code}

2:36 ignore the backtick... and it says "Routes must be either string or a vector, not a class"

2:37 ibdknox: what version of Noir?

2:37 nuclearsandwich: ibdknox: 1.2.2

2:38 ibdknox: weird

2:38 can I see a gist of the file? I just tried your code in a repl and it was fine

2:38 is there a symbol in that file for auth-callback?

2:40 nuclearsandwich: ibdknox: I try to use it in a (url-for )

2:41 As far as gisting the file, I'd have to sanitize it as it isn't mine.

2:41 ibdknox: hm, nothing is jumping out at me immediately

2:41 muhoo: wow, that's freaky. i actually think i understand aleph

2:42 ibdknox: Fwiw though, I've found that that pattern is actually best done by creating vars for the urls in a urls-file

2:42 since you'll run into cyclic deps

2:42 since you'll run into cyclic deps

2:42 muhoo: ibdknox: does the aleph port of noir actually work?

2:43 ibdknox: muhoo: it's not really a port, but yeah :)

2:43 muhoo: thanks

2:43 nuclearsandwich: ibdknox: what do you mean creating vars for the urls?

2:43 ibdknox: nuclearsandwich: so you do (def auth-callback "/auth/callback") (defpage auth-callback {code :code} ...)

2:43 then (url-for auth-callback ...)

2:44 nuclearsandwich: ibdknox: ah, makes sense. Will noir change to embrace this new pattern?

2:44 muhoo: aleph seems to me like the kind of thing node.js wants to be, but can't.

2:44 ibdknox: nuclearsandwich: the other way will continue to work, but my guidance henceforth will point in that direction

2:45 muhoo: aleph has a ways to go performance-wise

2:45 nuclearsandwich: it's far more robust

2:46 muhoo: ibdknox: really? what's the bottleneck?

2:46 ibdknox: muhoo: some of the abstractions are quite costly

2:46 nuclearsandwich: ibdknox: agreed. I am saving a paste of this conversation to use as evidence wen I am later asked wtf I am doing. :D

2:47 muhoo: i wondered about that. looking at the code, lots of deeply-nested namespaces

2:47 never a good sign

2:48 ibdknox: muhoo: he's working on it though :)

2:48 muhoo: good to know

2:49 bbloom: docs

2:50 ^^whoops wrong box

2:50 muhoo: sudo shutdown -h now

2:50 :-)

2:55 91 hours and counting into clojure, and 174 pages into joy of clojure, the first lightbulbs start to flicker on dimly.

2:59 johnmn3: would there be a way to attach clojurescript to a running browser?

8:26 gtrak: is there a simpler way to nest elts in a vector?

8:26 ,(map conj [1 2 3 4 5])

8:26 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (1) passed to: core$conj>

8:26 gtrak: ,(map #(conj nil %) [1 2 3 4 5])

8:26 clojurebot: ((1) (2) (3) (4) (5))

8:27 clgv: gtrak: what dou you want to do?

8:27 gtrak: what i just did there, but maybe there's a simpler way

8:28 cemerick: &(map vector (range 5))

8:28 lazybot: ⇒ ([0] [1] [2] [3] [4])

8:28 clgv: &(map list [1 2 3 4 5])

8:28 lazybot: ⇒ ((1) (2) (3) (4) (5))

8:28 gtrak: ah, slightly better

8:28 TimMc: gtrak: partition 1 ?

8:28 gtrak: hmm

8:29 ,(partition 1 (range 5))

8:29 clojurebot: ((0) (1) (2) (3) (4))

8:29 gtrak: ,(partition 2 (range 5))

8:29 clojurebot: ((0 1) (2 3))

8:30 gtrak: i see

8:31 TimMc: ,(partition-all 2 (range 5))

8:31 clojurebot: ((0 1) (2 3) (4))

8:32 TimMc: ,(partition-all 3 2 (range 10))

8:32 clojurebot: ((0 1 2) (2 3 4) (4 5 6) (6 7 8) (8 9))

8:32 gtrak: hmm, inclusive

8:32 very very nice

8:33 this kind of stuff is such a pain in java that you'd avoid it

8:34 jamii: is there an equivalent in clojure to the traditional zip?

8:35 (zip '(1 2 3) '(:a :b :c)) == '([1 :a] [2 :b] [3 :c])

8:36 Chousuke: jamii: map vector

8:36 gtrak: ,(map vector '(1 2 3) '(:a :b :c))

8:36 clojurebot: ([1 :a] [2 :b] [3 :c])

8:37 clgv: jamii: zipmap if you want a hashmap afterwards

8:37 jamii: oh, weird

8:37 thanks

8:37 gtrak: ,(into {} (map vector '(1 2 3) '(:a :b :c)))

8:37 clojurebot: {1 :a, 2 :b, 3 :c}

8:37 clgv: gtrak: zipmap is better for that ;)

8:39 jamii: I would have expected map to behave like for

8:39 gtrak: and join them together?

8:41 jamii: ,(for [x '(1 2 3) y '(:a :b :c)] [x y])

8:41 clojurebot: ([1 :a] [1 :b] [1 :c] [2 :a] [2 :b] ...)

8:42 gtrak: but that's what for is for

8:42 jamii: :)

8:42 ok

8:42 so now I have (for [[x y] (map vector ...)] ...)

8:44 clgv: jamii: what's the big picture?

8:45 jamii: I have a list of overtone instruments and a matching list of cpu stats. I want to periodically set the instruments freq/volume according to the cpu stats.

8:46 clgv: https://gist.github.com/1901031

8:46 Chousuke: jonasen: for is not meant to do side-effects

8:47 right, doseq will work

8:47 clgv: jamii: ok thats code. in words - what do you want to do? what is the input leading to which output?

8:47 jamii: Chousuke: I wrote it right in the gist (doseq)

8:48 clgv: the words came before the gist ^^^

8:49 clgv: jamii: there is no (for [[x y] (map vector ...)] ...) in it

8:49 jamii: clgv: its a (doseq [[inst cpu...

8:50 Its not a big deal, I was just wondering if thats really the most idiomatic way to do it

8:50 Chousuke: seems fine to me

8:51 jamii: Chousuke: thakns

8:52 clgv: jamii: looks fine in that context.

8:57 tsdh: What's the right function to convert a clojure value, where everything except nil and false is truthy, to a java boolean value?

8:58 (boolean 1) gives a reflection warning, so I probably have to go with (if value true false)?

9:00 si14: guys, can I ask here a question about ClojureScript?

9:00 TimMc: si14: Yes, that's in scope for the channel.

9:00 gtrak: Check out the other arities of partition, there's also a "fill" argument.

9:00 si14: ok :) here is it: how can I build stand-alone ClojureScript files without Noir?

9:01 I've followed some tutorials and it's clear; the problem is that I want to use ClojureScript without Clojure server in my production

9:02 TimMc: si14: CLJS includes a compiler shell script -- you can run that against your cljs files.

9:02 si14: I'm serving directory with simple html page with python in my dev environment and keep getting "GET http://localhost:8000/deps.js 404 (File not found)"

9:02 TimMc: I'm already using leiningen for this with it's "lein cljsbuild"

9:03 TimMc: (I've actually just reached the limits of my knowledge of CLJS development...)

9:04 si14: here is my files: https://gist.github.com/fe7bd94031a026b5fb9c

9:04 *are

9:07 timvisher: hey kids

9:08 is there a way to coerce an object into a readable string? I'm currently using `pr` to print it to a file, but i'd like to un-complect that

9:09 clgv: timvisher: pr-str?

9:09 timvisher: clgv: nice!

9:09 i had done a find-doc for reader

9:09 and nothing came back that looked interesting

9:09 :)

9:09 clgv: oh there was a 50% chance I was guessing your problem wrong ;)

9:10 timvisher: explain?

9:10 i'm trying to store a set for reading later via slurp

9:10 or rather

9:11 slurp and read-string

9:12 thought I remembered their being a load-file or something, but maybe there was a reason i didn't use that…

9:12 si14: so, how can I "statically" build CLJS?

9:13 without any external deps such as "deps.js"

9:13 timvisher: anyway, that's working fine, but my function calls (pr obj) internally and I'd rather define something that accepts something that is readable and just writes it to a file as is, rather than having it mashed together.

9:21 i'm trying to set up a generic interface with multimethods in a namespace that then would have multiple possible implementations that you can choose from via the dispatch method. The implementations would all be in their own namespaces, ideally, to separate the implementations out for readability. However, doesn't that lock me in to using or requiring all of the sub-namespaces whenever I want to call my generic interface m

9:22 is there a better way to accomplish what i'm going for?

9:25 clgv: you know 'print-method?

9:25 timvisher: clgv: me? I do not.

9:26 clgv: that multimethod is used for printing objects

9:26 timvisher: yeah, I meant you

9:26 timvisher: ok

9:27 clgv: in JoC there is an example for clojure.lang.PersistentQueue

9:27 timvisher: i should really just read the PC.8 chapter again

9:27 :)

9:27 `fogus: Queue Fish!

9:29 si14: TimMc: did you use hiccup?

9:31 clgv: `fogus: what?

9:32 timvisher: you mean chapter 9 on multimethods?

9:33 si14: how can I generate a bunch of divs with different margins with crate?

9:35 timvisher: clgv: 8 for me. i think i'm still back on v1 or something

9:35 clgv: timvisher: lol k. there is a metadata chapter at 8 in my copy

10:00 TimMc: si14: Did I use Hiccup where?

10:02 clgv: is there a leiningen task that only updates resources in a jar/uberjar?

10:34 si14: TimMc: nevermind, already figured out myself :)

11:26 jaley: any recommendations for performance testing? I have a couple of functions I want to monitor performance of. I thought there was some function in clojure.test, but appears I was wrong.

11:28 Bronsa: maybe https://github.com/hugoduncan/criterium ?

11:28 mabes: +1 criterium

11:30 jaley: Bronsa, mabes: thanks for the recommendation, will take a look

11:38 bsteuber: cemerick: finally saw the 2nd half of your talk, nice framework

11:39 actually I was close to doing sth. like raposo in CL for my master thesis

11:39 but than I chose to turn haskell into a lisp instead :)

11:39 s/than/then

11:46 magnars: I must be doing something wrong, because my code is littered with (filter identity ...) and to a lesser degree (flatten ...) after recursing over a tree structure to gather information. What would be an idiomatic way of traversing a tree structure, and returning information about a subset of the nodes?

11:46 RickInGA: tree-seq

11:46 &(doc tree-seq)

11:46 lazybot: ⇒ "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of th... https://refheap.com/paste/821

11:46 raek: magnars: maybe mapcat?

11:47 magnars: hmm, those are both intriguing. Thanks, I'll give them a go.

11:47 raek: magnars: also, note that (flatten x) is not the same as (apply concat x)

11:47 magnars: flatten removes multiple levels of nesting

11:48 magnars: raek: yes, that has bitten me hard a couple of times - luckily I'm writing tests as I go along.

11:48 apply concat looks nice

11:48 RickInGA: magnars: I want to start testing, what do use? closure.test? midje?

11:49 magnars: RickInGA: I just wanted to get started quickly, so went for simple clojure.test

11:49 TimMc: magnars: for, with :let and :while and :when

11:50 magnars: TimMc: oh, hm, that's interesting. Thanks, now I have another three tools to try out.

11:51 TimMc: magnars: Multi-level for is great for fixed-depth data structures.

11:51 tree-seq is great if you have varying depth

11:52 magnars: tree-seq looks very promising

12:03 clgv: RickInGA: midje has some nice checkers for sequences hashmaps...

12:05 RickInGA: clgv: you think if I am just getting started with testing in clojure, I should just start with midje?

12:05 tripodman: is clojure fairly easy to set up on a small vps for someone with little experience?

12:06 clgv: RickInGA: well, if you have more complex result data to check it can pay off to use midje. you can just try pure clojure.test and then midje afterwards. that shouldnt consume that much time

12:06 RickInGA: tripodman: in my experience, setting up clojure is 2 things, setting up leiningen (build tool) and setting up an editor

12:07 leiningen will build your clojure environment for you.

12:07 tripodman: RickInGA: awesome i'll look into that

12:07 clgv: tripodman: if you are familiar with eclipse you can also checkout CCW

12:08 RickInGA: If you have an editor/ide you like you can get a clojure plugin

12:08 tripodman: cool ty

12:08 RickInGA: if you aren't familiar with any editors on the java or *nix platforms (like me) , checkout clooj

12:10 jamii: https://github.com/jamii/mechanical-sympathiser

12:10 my first clojure project, its alive!

12:11 mdeboard: I'm sorry

12:11 krl: if i have a namespace X with a defrecord, of a protocol in namespace Y, and a namespace Z that :uses X, do i need something special for clojure to recognize a method of the protocol?

12:12 clgv: krl: you will always have to :use or :require that namespace to use the methods of the protocol

12:12 krl: ok, thanks.

12:13 RickInGA: jamii: your computer makes noise if you overwork it?

12:14 jamii: RickInGA: at the moment, each cpu gets a pure sine wave tone with the volume corresponding to the cpu load

12:14 (with the cpus tuned in perfect fifths so they make nice chords)

12:14 RickInGA: nice!

12:15 rplevy: dsantiago: Hi. what kind of setup is required in order to successfully run the tests for clojure-hbase? I am able to connect to hbase via hbase shell, but I get java.lang.reflect.InvocationTargetException caused by an IllegalArgumentException Not a host:port pair: �

12:15 jamii: I'm going to add a bunch of other sounds and data sources

12:15 RickInGA: wasn't the 5th considered the devil interval in the middle ages? fits with my theory that computers are evil.

12:15 rplevy: when I run lein test that is

12:15 jamii: RickInGA: flatted fifth

12:16 RickInGA: the fifth sounds nice

12:16 rplevy: jamii: discordianism / law of fives ;)

12:16 dsantiago: rplevy: Hi, hang on a second.

12:17 rplevy: dsantiago: thanks!

12:17 clgv: ,(+ 2 3)

12:17 clojurebot: 5

12:17 clgv: ;)

12:18 jamii: rplevy: Interestingly, it seems that both chromatic and pentatonic scales come from trying to fit fifths (ie 3/2 ratios) and octaves (2/1 ratios) into the same system

12:18 RickInGA: jamii: you are right, flatted fifth is devils interval, makes more sense.

12:18 jamii: rplevy: http://www.math.niu.edu/~rusin/uses-math/music/

12:21 no, wait, http://www.math.niu.edu/~rusin/uses-math/music/12

12:22 RickInGA: jamii: nice application for overtone

12:22 jamii: RickInGA: thanks

12:22 RickInGA: I hope to actually make music eventually, but one thing at a time

12:22 Learning clojure + overtone + composing all at once would be hard

12:22 rplevy: dsantiago: btw I am running the thrift service on localhost

12:23 RickInGA: I can run overtone from lein repl, or from repl in emacs if I start swank externally

12:23 dsantiago: rplevy: So when I run the tests, I always run it in standalone mode on version 0.90.5.

12:23 No configuration is required.

12:23 I have had problems with connecting to it, and this is a known issue in HBase, when there are multiple entries for localhost in hosts.conf.

12:23 So lately I've had to comment some of those out in order to run the tests.

12:24 But I can't remember if that is the exception that gets thrown then.

12:24 RickInGA: but when I try to use overtone.live from editor and try to evaluate I crash

12:24 rplevy: dsantiago: interesting, I'll try these tips, thanks!

12:30 dsantiago: I mean /etc/hosts, not hosts.conf.

12:31 rplevy: yup

12:32 that doesn't seem to fix my problem though, I'll try installing hbase 0.90.5 (I'm on 0.92.0)

12:41 dsantiago: rplevy: OK, I haven't tested with .92.

12:43 Are they just going to not put those in maven or what?

13:08 TimMc: cemerick: Why do you call proxy and gen-class the "interop zone"? I think of deftype and reify as interop as well.

13:56 cemerick: bsteuber: thanks; obviously, it's not finished yet, or really in a releasable state :-(

13:59 TimMc: Because proxy and gen-class are fundamentally associated with the JVM's semantics and constructs. deftype et al. are "Clojure native" insofar as they should translate well to other hosts (witness ClojureCLR and ClojureScript, neither of which have gen-class).

14:00 Also, deftype would work fine from within Clojure even if it had been implemented some other way that didn't involve an interop-friendly manifestation.

14:00 TimMc: Hmm, OK.

14:01 cemerick: I'm open to counterarguments / suggestions on the diagram; not too late yet :-)

14:01 TimMc: I'm makin' a spreadsheet.

14:02 (purely for organizing my thoughts)

14:09 rplevy: dsantiago: I've confirmed that it was the client / server version difference that was the problem (they should really add 92.x to maven, or is that not considered stable yet?)

14:16 dsantiago: rplevy: I actually don't know. I assume if it's not in maven, it's not released.

14:17 rplevy: yeah, that makes sense. though I remember Jython for example took a couple years to get their latest version into maven once, so I guess it's not always the practice, haha.

14:36 ferd: I need a customizable bot for IRC and XMPP. Written in clojure I see lazybot, sexpbot (deprecated?), clojurebot. Any recommendations?

14:36 hiredman: clojurebot's xmpp support is currently limited to non-existent

14:36 miltondsilva: hmm.. using clojure 1.4 beta-1... I get some weird results http://pastebin.com/CbdexLYQ shouldn't the areduce be faster than reduce?

14:37 hiredman: earlier versions had support but it was dropped as part of a rewrite

14:37 a good clojure xmpp library would be nice

14:39 miltondsilva: oh, forget it, there was a missing ^ints hint

14:39 amalloy: sexpbot is an older lazybot

14:39 ferd: Thanks... After a quick look, it seems like lazybot is easier to extend (at least it has some documentation)

14:39 gfredericks: older and wiser

14:40 amalloy: there was an effort to make lazybot support twitter too, but it was abandoned. apparently like clojurebot's xmpp support

14:40 ferd: amalloy: thanks, that's what I imagined... You might want to put a banner on its README on github pointing to lazybot

14:42 hiredman: I think the lack of good xmpp libraries is a testament to its complexity

14:42 amalloy: ferd: yeah, i thought we already had. done now

14:43 twhume: I'm a total Clojure newbie. Am working through the book, writing my very first functions. Is there a better place than here to ask really trivial questions?

14:43 technomancy: ask the repl first =)

14:44 amalloy: or ask lazybot if you haven't gotten your own repl set up satisfactorily

14:45 well, i guess http://tryclj.com/ would be easier than that :P

14:45 dnolen: twhume: this is the ultimate stopping point for really trivial Clojure questions ;)

14:45 twhume: I have a REPL going, and counterclockwise w/Eclipse; and I have functions running.

14:45 OK, I'll shoot…

14:46 eggsby: I'm another total clojure newbie twhume, nice to meet you!

14:46 i've been using http://4clojure.com its been pretty good to me so far

14:47 twhume: I've implemented my own version of the frequencies function, just to kick off. It seems to work, in that when I print out the results of running my function and running frequencies() on the same string, the REPL prints the same thing. I thought I'd add a unit test to check for equivalence of the two maps produced, and this is where I'm stuck...

14:47 My function is called digest:

14:47 => (println (digest "the quick brown fox jumps over the lazy dogg"))

14:47 {the 2, quick 1, brown 1, fox 1, jumps 1, over 1, lazy 1, dogg 1}

14:47 => (println (= [frequencies (str/split "the quick brown fox jumps over the lazy dog" #"\s") digest "the quick brown fox jumps over the lazy dogg"]))

14:47 true

14:47 nil

14:48 amalloy: your []s and ()s are nuts in that

14:48 TimMc: twhume: No need for println

14:48 amalloy: (= (frequencies (str/split "the quick brown fox jumps over the lazy dog" #"\s")) (digest "the quick brown fox jumps over the lazy dogg"))

14:49 TimMc: twhume: (= only-one-thing) always returns true

14:49 twhume: Thanks

14:50 Thanks very much - I've misread the clojure quick reference, and thought = had to be passed a list.

14:50 Much appreciated.

14:51 babilen: twhume: You might find http://clojuredocs.org/, http://www.4clojure.com/ and http://clojure.org/cheatsheet helpful btw (just saying)

14:52 twhume: Thanks babilen - I hadn't come across 4clojure before. Will self-flagellate and look around harder before next time. Cheers for your help everyone!

14:54 magnars: RickInGA and TimMc: thanks a bunch for the tip about tree-seq earlier - just the function I needed. I'm thrilled!

14:54 the-kenny: Is there a reason why clojurescript doesn't feature `case'?

14:56 TimMc: the-kenny: I would guess that JS doesn't support that sort of fast literal branching.

14:56 the-kenny: Hm :(

14:56 amalloy: i was thinking that too, but...

14:56 TimMc: Or no one has implemented it. :-)

14:56 amalloy: even if it did, perhaps case couldn't be implemented the same way it is in clojure

14:56 the-kenny: Why not do a fallback to (cond ((= op v) ..) ((= op w) ...))?

14:57 (I'm currently working with code shared between clojure & clojurescript)

14:57 amalloy: clojure computes some hashcodes at compile-time, and then switches on them at run-time. in cljs, the compile-time hashes will be in java, but in cljs they'll be js

14:58 the-kenny: Hm, if it's not available, I'll rewrite this function using multimethods. Performance shouldn't be a problem

15:05 jrobie: i'm sure this is a newbie FAQ, but is there a reason to prefer cons vs. conj?

15:06 TimMc: amalloy: I'm guessing it uses the same bytecode behind Java's switch.

15:06 amalloy: TimMc: have you looked? it uses switch but does a lot of stuff before that because switch only supports ints

15:06 TimMc: hah

15:07 lucian: it could use Object.hashCode and switch on that, with a check

15:08 scriptor: jrobie: conj's behavior is dependent on the implementation

15:08 that's why conj appends to the end for a vector and the beginning for a list

15:08 jrobie: thanks, scriptor

15:08 * jrobie is obviously working through the tutorial for the first time

15:09 gtrak``: ,(conj (seq [1 2 3]) 4)

15:09 clojurebot: (4 1 2 3)

15:09 TimMc: jrobie: cons always produces a seq with the new element at the front

15:09 jrobie: these results surprised me

15:09 user=> (conj (list "one" "two" "three") "four")

15:09 ("four" "one" "two" "three")

15:09 user=> (cons (list "one" "two" "three") "four")

15:09 (("one" "two" "three") \f \o \u \r)

15:09 TimMc: no matter what the collection was

15:10 jrobie: argument order

15:10 jrobie: is \f \o \u \r the same as "four"?

15:10 hiredman: have you read the docstring for those functions?

15:10 TimMc: &(seq "four")

15:10 lazybot: ⇒ (\f \o \u \r)

15:10 jrobie: thanks, hiredman, shoulda done that

15:10 gtrak``: jrobie: cons and conj flip the seq and the value argument to make it more obvious I guess?

15:10 scriptor: jrobie: the order of what argument is what is different for conj and cons

15:11 TimMc: scriptor: that's *one* difference, yes

15:11 scriptor: TimMc: yea, not sure why I said "what is"

15:11 I explained another difference earlier

15:12 gtrak``: looking at RT.java, conj calls .cons on the collection object, which is polymorphic

15:12 scriptor: yep

15:12 jrobie: one Big Picture question: when should i use clojure vs scala vs. java?

15:12 gtrak``: ,(class (seq [1]))

15:12 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

15:12 gfredericks: use java for implementing Clojure

15:12 jrobie: another Big Picture question: is there anything like Scala's Parser Combinators or Haskell's Parsec or Haskell's Happy for Clojure?

15:12 scriptor: use scala if you like it's type system, I guess

15:13 I don't know that much about it

15:13 jrobie: yep, there was a big discussion about clojure parsers on the mailing list, one sec

15:13 gtrak``: ah, chunkedseq extends ASeq, that's why that works

15:13 technomancy: there's a parsec port

15:13 hagna: in (defmulti compiler :os) I guess :os is the dispatch function, but it's a keyword huh?

15:13 lucian: jrobie: all three are general purpose, use whichever you like

15:13 hagna: keywords are functions

15:14 TimMc: &(instance? clojure.lang.IFn :foo)

15:14 lazybot: ⇒ true

15:14 jrobie: a parsec port would make me happy. (DSLs are one of the things i most like to do)

15:14 hagna: lucian: ok I guess that's why I can do (:keyword map)

15:14 gtrak``: ASeq cons returns new Cons(o, this);, PersistentVector.cons pushes it on the tail

15:14 scriptor: jrobie: some parsec-like things are mentioned here http://groups.google.com/group/clojure/browse_thread/thread/d9f18dba071d903a/eb0c7381f4ffcf29?lnk=gst&q=parser

15:15 gtrak``: a seq view of a vector is still an ASeq implementation, and conj's like ASeq

15:15 jrobie: thanks, scriptor

15:15 gtrak``: jrobie: check out parsatron

15:15 jrobie: thanks, gtrak

15:15 gtrak``: that's what it's meant to be

15:16 jrobie: gtrak, what do you particularly like about parsatron?

15:16 gtrak``: Nate's a nice guy? :-)

15:17 I don't know that much about parsers, but I think we're using it internally for some stuff

15:17 jrobie: i like nice guys, i'm mostly hoping for something that reads like the original grammar, like parsec or parser combinators

15:17 especially if it's also efficient

15:18 gtrak``: jrobie: he gave a talk on it at strangeloop, you could watch that

15:18 technomancy: the strangeloop talk on parsatron was great

15:18 gtrak``: http://www.infoq.com/presentations/Parser-Combinators

15:18 eggsby: I thought that was mostly on parsec?

15:18 gtrak``: no, he showed stuff in parsatron

15:19 eggsby: ah

15:19 but ya that talk was great

15:20 jrobie: hmmm, he says most of his talk comes from walking through the parsec source

15:23 gtrak``: jrobie: the whole project looks quite small

15:26 jrobie: lein is the package manager for clojure, right? so how do i install parsec with lein?

15:26 TimMc: jrobie: It's not actually a package manager.

15:27 jrobie: ah

15:27 *is* there a package manager?

15:28 lucian: jrobie: it's more like virtualenv + pip if you've used python

15:28 cemerick: jrobie: clojure libraries are .jar files, and so they aren't "installed"; you declare dependencies on them in your project.clj file, and leiningen obtains them when necessary

15:28 lucian: or rvm + gem if you've used ruby

15:29 jrobie: ok, that makes sense

15:30 amalloy: has anyone thought about why we have (dissoc m :a :b) but (select-keys m [:a :b])? i just noticed and it seems weird

15:30 * technomancy likes the term "project automation"

15:30 technomancy: amalloy: the dissoc/disj split is werid too

15:31 amalloy: is it?

15:31 ibdknox|away: it's more common to select keys based on a collection you build over time?

15:32 * TimMc takes away everyone's varargs

15:32 technomancy: I expected to be able to dissoc out of a set, but maybe that's silly

15:32 TimMc: There, it's all easy now.

15:32 ibdknox|away: technomancy: I did too

15:42 amalloy: i think everyone expects that once. but you can't assoc into a set, and nobody seems to be surprised by that

15:43 TimMc: sets do a better job than maps of pretending to not be key-value pair collections

16:01 jrobie: i've defined a function in a buffer in emacs, and did M-x run-lisp, now i put my cursor at the end of a function invocation and do C-x C-e ... no dice

16:02 if i position the cursor after (+ 1 4), it works great

16:02 what am i missing?

16:04 mdeboard: jrobie: What does no dice mean

16:04 gfredericks: mdeboard: it don't work

16:04 mdeboard: gfredericks: Yeah was looking for specifics :P

16:04 jrobie: mdeboard, "no dice" is spelled user=> java.lang.IllegalStateException: Var user/pig-latin is unbound. (NO_SOURCE_FILE:0)

16:04 gfredericks: oh

16:05 jrobie: hah! turns out the parsatron guy is working on pig latin, i'm working on jsoniq, very similar projects

16:06 (where his pig latin is a query language, and has nothing to do with the example at hand)

16:09 mdeboard, did the error message help? the file has been saved

16:09 mdeboard: Oh I thought your problem was resolved, guess I misunderstood

16:10 jrobie: i get this when i try to evaluate a function call: user=> java.lang.IllegalStateException: Var user/pig-latin is unbound. (NO_SOURCE_FILE:0)

16:10 clojure-mode, lisp

16:10 mdeboard: are you in clojure mode

16:10 :D

16:10 jrobie: if i do the same for (+ 1 3), i get 4

16:10 mdeboard: I got nothin'

16:10 jrobie: well, i'm in clojure mode if the expression is (+ 1 3) ;->

16:11 did you do M-x run-lisp?

16:11 mdeboard: Well, (+ 1 3) is properly evaluated in elisp as well

16:11 TimMc: jrobie: Presumably there's a bug in your code?

16:11 jrobie: TimMc - i doubt it, i copied and pasted it from the tutorial, i can copy it and paste it into the interpreter and it works

16:11 TimMc: hmm

16:12 mdeboard: jrobie: Can you paste the exact code you're trying to evaluate

16:13 TimMc: jrobie: refheap.com

16:14 mdeboard: Oh a new pastebin

16:14 Since scpaste doesn't like naquadah theme :-\

16:14 jrobie: http://fpaste.org/JLVD/

16:14 TimMc: mdeboard: Raynes'

16:15 jrobie: if i evaluate the (defn) in the interpreter first, then i can evaluate line 11 or line 12

16:15 if not, i get that error

16:15 mdeboard: jrobie: Dunno, runs perfect for me in clojure mode

16:16 TimMc: jrobie: How else would you expect the defn to be visible to the later expressions?

16:20 jrobie: TimMc, mdeboard - i must be missing a step. is there a way to process all (defn)s in a buffer so i can evaluate expressions?

16:20 if i do that by hand (cut and paste into the inferior lisp buffer), it works fine

16:21 TimMc: I believe there is a command for that, yes -- I don't use swank myself, so I don't know what it is.

16:21 jrobie: ok, thanks - i'll look around

16:21 mdeboard: jrobie: There's M-x slime-eval-region and M-x slime-eval-buffer

16:22 jrobie: thanks, mdeboard !

16:22 mdeboard: np

16:25 photex: mdeboard is slime-eval-buffer different than C-c C-l ?

16:25 mdeboard: photex: I dunno

16:25 photex: sorry to chime in, but I'm new to the swanky universe as well, and have been using that to evaluate my file

16:26 oh

16:26 that is slime-load-file

16:26 mdeboard: Youc an do C-h w

16:26 then type the command to get the hotkey

16:26 TimMc: photex: C-h k C-c C-l will tell you what C-c C-l does

16:26 Bronsa: oh god, dem many C-*

16:26 TimMc: s/does/is bound to/

16:27 photex: ok, C-c C-l loads a file, slime-eval-buffer is not bound

16:27 TimMc: (Make sure you do it in the right mode.)

16:29 photex: checked from clojure mode

16:30 seems like it would save time to map slime-eval-buffer to a key

16:30 not sure how often I'd just load a file I didn't already have open

16:30 jrobie: photex, C-c C-l works for me

16:31 photex: but it asks for the filename first

16:31 TimMc: I'm on the verge of trying to figure out how to add a keybinding for paredit-convolute-sexp

16:34 photex: oh snap C-c C-c

16:51 mdeboard: I feel like whoever made these 4clojure problems knew exactly what my first-pass solution would be, and wrote the last test specifically to foil it, every time.

17:08 callen: mdeboard: aye, they did.

17:09 mdeboard: they want to force you to learn something, so they eliminate the shortcuts that occur on the way there.

17:09 lake: I would like to get autocomplete inside of the clojure repl (clj). Is it possible?

17:09 technomancy: lake: leiningen 2 has that

17:09 callen: technomancy: o_O

17:09 technomancy: clj is weak sauce though; you will want to ditch that

17:09 callen: oh, so you mean in slime?

17:10 technomancy: callen: no, jline2

17:10 "the jline that isn't terrible"

17:10 callen: so lein repl then.

17:10 technomancy: it's pretty slick

17:10 yeah

17:10 callen: technomancy: what about auto-complete for clojure-mode and slime that doesn't rely on my magic autocomplete?

17:10 muhoo: is the idiomatic way to loop over stuff for side effects to (doall (for [b something] (stuff b))), or is there a better way?

17:11 pandeiro: muhoo: doseq?

17:11 callen: to be fair, I saw Hickey's code do that in the concurrency talk IIRC

17:11 technomancy: callen: M-tab should do smarter completion

17:11 smarter than dabbrev, for when you need it

17:11 callen: smarter...as in...knows the classpath?

17:12 technomancy: yeah

17:12 well, for everything that's already been required

17:12 and java static stuff

17:12 callen: okay. that seems good.

17:12 technomancy: it is!

17:12 it's pretty good, I mean

17:12 still no method completion on type-hinted locals

17:12 that would be the best

17:12 muhoo: pandeiro: thanks, that seems better

17:16 lake: technomancy: my version of lein is 1.7, having trouble finding version 2

17:17 should i just use clojure-mode in emacs? would that give me autocompltere

17:17 autocomplete*

17:17 technomancy: lake: sorry; should have mentioned it's not technically released yet

17:17 actually I think you can use lein2's repl in lein1 with a plugin

17:17 clojurebot: reply?

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

17:17 technomancy: clojurebot: reply is the new high-powered repl that powers lein2's repl task https://github.com/trptcolin/reply

17:17 clojurebot: c'est bon!

17:18 trptcolin: lol @high-powered :)

17:18 emezeske: technomancy: So I *think* the only task that remains for cljsbuild to support lein2 is updating its hooks

17:19 technomancy: But I am a little confused about how they need to change

17:19 technomancy: The existing hooks look like the ones here: https://github.com/technomancy/robert-hooke/blob/master/README.md

17:19 muhoo: clojurebot: it's greek to me too.

17:19 clojurebot: Cool story bro.

17:20 emezeske: technomancy: But they're doing weird things when 'eval-in-project' is called

17:20 technomancy: emezeske: what functions are you hooking?

17:21 emezeske: jar/write-jar clean/clean test/test compile/compile

17:21 technomancy: emezeske: write-jar is the only one that may have changed

17:21 lake: technomancy, trptcolin: reply is working well. thanks for your contributions to the community!

17:21 technomancy: emezeske: actually scratch that; it hasn't

17:22 emezeske: technomancy: Hmm, I've tried various combinations of commenting out each hook independently, they all seem to do odd things

17:22 trptcolin: lake: great, glad to hear it! please do open github issues if you have ideas on things you'd like to see

17:22 technomancy: trptcolin: does it work as a lein1 plugin now?

17:23 emezeske: technomancy: It's like when eval-in-project is called, the hook code is somehow getting executed

17:23 trptcolin: i haven't tackled that yet

17:23 technomancy: but it's still usable via the shell script?

17:23 trptcolin: right. thanks for the reminder though, i'll add an issue for a lein1 plugin

17:27 emezeske: technomancy: Okay, so what seems to be happening is that leiningen.core.main/apply-task is somehow being invoked inside the subproject when my code calls eval-in-project

17:27 technomancy: whoa; that's crazy

17:27 emezeske: technomancy: https://refheap.com/paste/822

17:28 technomancy: line 38 is where eval-in-project is called

17:28 technomancy: emezeske: oh, ok

17:28 before you run any code inside the project, you have to prep it

17:28 this means seeing if you need to do any AOT or javac

17:29 so eval-in-project is triggering the hook you added to the compile task

17:29 emezeske: ahh, preparing the project involves compiling it

17:30 the thing I don't understand is, why does the subproject see my hooks?

17:30 I am not passing through the :plugins

17:30 technomancy: it never gets to the subprocess

17:30 emezeske: ohh

17:30 the preparations happen in the parent?

17:30 so somehow I need to unhook my hooks right before calling eval-in-project

17:30 technomancy: well, the compilation should happen inside the project, but your hook is blowing up before it reaches that

17:31 emezeske: the subproject is being passed to my hook, and the subproject doesn't have the :cljsbuild config in it

17:31 so my hook blows up with "hey no :cljsbuild config found"

17:32 I wonder if there's something better for me to hook than compile/compile

17:32 anyway, thanks for the insight, I think I at least get why this is happening now

17:32 technomancy: oh, maybe check the leiningen.core.eval/*prepping?* flag?

17:32

17:33 emezeske: ooh

17:33 that might do the trick

17:33 technomancy: won't work in 1.x

17:33 emezeske: that's easy enough to deal with

17:40 hagna: Raynes: is irclj supposed to work with clojure 1.3?

17:42 aaelony: RickInGA: Devil's interval is the tritone

17:45 hagna: aaelony: heh maybe in the 1800s

17:50 muhoo: i love tritones

17:50 i've used them a lot in my devil's music.

17:54 aaelony: hagna: even today. tritone substitution is pretty common in jazz as well

18:01 muhoo: what is import-fn?

18:01 i see it all over the place in aleph code, but can't figure out where it is coming from

18:01 actually it's in gloss, everywhere. still can't figure out where it is coming from though.

18:02 Raynes: Insane is what it is.

18:02 http://github.com/ztellman/potemkin it's the most vile thing ever thought up.

18:03 muhoo: :-/

18:03 great

18:04 can you recommend good asynchronous network socket stuff for clj that is not based on things that are "vile" and "insane" ?

18:04 because i was really liking aleph. until now.

18:04 Raynes: Well, Aleph is actually pretty good.

18:05 muhoo: but it's based on potemkin

18:05 well, let me be clear, it's based on a million things, including gloss, which is based on potemkin

18:05 Raynes: 'based' is the wrong word here

18:05 You shouldn't really have to know that it uses potemkin under the hood.

18:05 Unless, of course, you're digging around for some reason

18:05 muhoo: no, but if i'm tracing the source code to see what it does

18:06 i have to go deeper, and deeper, and deeper..

18:06 and i find stuff that is "vile", i get worried.

18:06 Raynes: Heh

18:06 muhoo: like, maybe i shouldn't be wasting time with this.

18:06 Raynes: Well, anyways, aleph and gloss are generally excellent things.

18:06 muhoo: maybe i should ask if there's a better option

18:07 Raynes: Take a deep breath.

18:07 muhoo: i'm not trippin.

18:07 hagna: aaelony: b eb e a

18:07 muhoo: just amused, mostly.

18:07 Raynes: hagna: It should work on 1.3, theoretically. I think I tested it against 1.3.

18:08 muhoo: seriously, what's so wrong with potemkin?

18:08 callen: I'm wondering too.

18:09 muhoo: hmm, i think i see https://github.com/ztellman/potemkin/blob/master/src/potemkin/namespace.clj

18:09 why would he be writing a macro to import functions from another namespace?

18:09 what's wrong with use?

18:09 Raynes: It is a bandaid over bad library organization.

18:09 muhoo: aye

18:10 callen: that's pretty strange.

18:10 hagna: Raynes: well in lib/irclj-0.5.0-20111019.122151-1.jar I get an error about not resolving send-message on core.clj:65

18:10 callen: the throw-arity stuff is pretty hilarious.

18:10 Raynes: I'm not sure I actually released any snapshots of the rewrite because it wasn't finished.

18:11 TimMc: Anything named "potemkin" has a good chance of hideousness.

18:11 muhoo: i mean, i don't want to slag the dude, he's obviously way more skilled than me

18:11 Raynes: https://github.com/ztellman/potemkin/blob/master/src/potemkin/map.clj#L30

18:11 muhoo: still, i don't want to learn how to write stuff that's "vile", nor base my apps on it

18:11 Raynes: Dear God.

18:12 callen: so.

18:12 ibdknox|away: lol

18:12 callen: tellman is a madman, right?

18:12 muhoo: what the screaming fuck?

18:12 * muhoo scratches aleph off the list

18:12 * Raynes chuckles

18:12 Raynes: There aren't really any good alternatives.

18:13 hagna: Raynes: so that's idiomatic clojure?

18:13 Raynes: This shit I just linked to?

18:13 hagna: :)

18:13 Raynes: I don't even know what this *is*, but I highly doubt it is a good idea.

18:13 muhoo: no "If your name isn't Rich, don't write a form as long as, say, the definition of doseq."

18:13 http://dev.clojure.org/display/design/Library+Coding+Standards

18:14 ibdknox: in general, much of core serves as an example of how not to write idiomatic clojure ;)

18:14 callen: so are there any alternatives to Aleph, or is this the bed we've made?

18:14 * muhoo eagerly awaits the answer to that question

18:14 Raynes: Well, keep in mind that Aleph isn't potemkin.

18:14 hiredman: really?

18:14 Raynes: It just used the library for whatever reason.

18:15 muhoo: no, it just calls gloss which calls potemkin

18:15 which mean throw-arity will appear in your stacktrace, sometime, when you least expect it :-)

18:15 Raynes: I don't much like Java, but Clojure calls Java under the hood sometimes. :p

18:15 muhoo: good point.

18:15 Raynes: Though I feel your throw-arity pain.

18:15 ibdknox: I wouldn't let the implementation detail distract from the use of the lib

18:16 emezeske: x86_64 assembly is a beast too, and it's even harder to get away from

18:16 Raynes: ibdknox: I think his biggest issue is that it muddles the stacktraces.

18:16 Which is a serious problem, if true.

18:16 ibdknox: hm yeah

18:16 muhoo: no, i'm just scared that i'll be faced with a problem and be stuck in a corner having to deal with code like that

18:16 ibdknox: ah, it should limit you

18:16 I wouldn't worry about that

18:17 Raynes: shouldn't*

18:17 ibdknox: yeah, sorry. shouldn't limit you

18:17 muhoo: this is interesting

18:18 in other languages, i'm used to crappy code in underlying libraries bubbling up and causing me Pain and Anxiety

18:18 i'm getting the sense that in clojure perhaps it's not as much a concern?

18:18 accel: I wnat to delete an element from a map; I don't want to do (merge MAP {:key nil}) ... is there an away to actually delete the entry?

18:18 ibdknox: accel: dissoc

18:19 muhoo: but it does limit my ability to reason about the code

18:19 ibdknox: you shouldn't have to think down at that level

18:19 if you do, there's something wrong with the lib

18:20 muhoo: well, or with me. but it's possible in this case, that it's the lib.

18:20 here's what i was trying to do, as an example

18:20 Kowboy: ibdknox, considering your work on jayq, do you have any thoughts on using modernizr with cljs?

18:20 muhoo: i was trying to figure out how to stop an http server created with start-http-server

18:21 accel: ,(doc dissoc)

18:21 clojurebot: "([map] [map key] [map key & ks]); dissoc[iate]. Returns a new map of the same (hashed/sorted) type, that does not contain a mapping for key(s)."

18:21 accel: ibdknox: nice; thanks

18:21 muhoo: there is no stop-http-server. so i'm tracing the code of start-http-server, to see if anywhere there's some *thing* i can grab onto, and call some kind of (stop *thing*) on it

18:21 ibdknox: muhoo: it used to be that it returned a function that you could use to stop it

18:22 muhoo: and only 2 layers deep i get to gloss, calling import-fn, and that let me to that brain-exploding namespace.clj page

18:22 it returns a function, but it's unclear to me what the function does :-/

18:22 ibdknox: Kowboy: it'd probably look similar to jayq

18:22 muhoo: again, sent me diving into the source to try to figure it out

18:23 ibdknox: muhoo: that's a documentation problem

18:23 mention it on the aleph list, Zach is usually very good about trying to clear those up

18:23 muhoo: ok, will do, thanks.

18:23 Kowboy: maybe I found something I can contribute then

18:23 hmmm

18:24 ibdknox: it'd actually be quite a bit simpler than jayq

18:24 since you don't have an object you'd need to extend to the collection stuff

18:28 muhoo: ibdknox: got it, (defn start-server "Starts a server. Returns a function that stops the server."

18:29 start-http-server calls start-server, and bob's yer uncle.\

18:29 ibdknox: that's annoying

18:29 that docstring should be on start-http-server as well

18:29 I'd file a bug

18:29 muhoo: will do

18:30 doesn't functional programming tail-recurse docstrings? :-)

18:31 callen: do ho ho.

18:31 we got a comedian here.

18:32 qbg: Real programmers read the generated byte code instead

18:32 callen: I thought they wrote Fortran instead.

18:36 Kowboy: ibdknox, " Virtually the entire web is built on $ and that means nearly every computer connected to the internet already has a google CDN'd version of jquery on their machine."

18:36 that's not necessarily true of modernizr

18:36 but I don't think it is very big anyway

18:37 pandeiro: what would be the expected behavior for let bindings inside a doseq in cljs? i thought i could use the let bound symbols in event handlers because cljs would be doing some gensym for the actual var names but that's not the case.

18:37 ibdknox: Kowboy: using modernizr is a much higher-level choice

18:37 you can't really do much in JS without dom manipulation, and so no matter what you need goog.* or jquery or mootools or something

18:38 people who want to use modernizr are explicitly making a trade-off

18:38 Kowboy: in short, I don't think that point is nearly as important in that case :)

18:39 Kowboy: I see

18:39 is it even worth wrapping with cljs?

18:41 ibdknox: not sure, I haven't used enough to know how much code you actually have write to use it

18:41 I thought actually you didn't really have to write anything

18:42 lynaghk`: Kowboy, Modernizr is not very large, and there is a custom build tool online that lets you pick out only the features you want to detect

18:42 pandeiro: Kowboy: i'd say it depends what features you need to detect... if it's just 2-3 things i'd just write cljs fns to do it the same way Modernizr does it, that's what I've done for things eg localStorage support

18:51 k answering myself, no, let bindings inside doseq in cljs do not behave as they do in clojure...

18:51 ibdknox: pandeiro: hm?

18:53 pandeiro: ibdknox: if you do let bindings inside a doseq in cljs, the references shadow each other if you're using those bindings for say event handlers

18:54 hiredman: there is an open bug for it, dnolen was discussing it in here the other day

18:54 callen: AHA, antirez is an Emacs user.

18:54 I knew it.

18:54 pandeiro: hiredman: ah ok, so i won't make a ticket then

18:54 ibdknox: ah

18:54 that

18:57 technomancy: emezeske: were you going to use prep-tasks in lein-cljsbuild?

19:02 emezeske: technomancy: yeah, that's my plan

19:03 technomancy: basically just make my hooks noops if it's set

19:03 technomancy: emezeske: ok, I just pushed out a change that might affect you

19:03 the list of prep tasks to run gets passed around in the project map now

19:04 it's possible that instead of adding hooks, you could just tell the user to put :prep-tasks ["cljsbuild"] into project.clj

19:05 I can elaborate if you need

19:05 emezeske: technomancy: hmm, would that work for e.g. what is now the "lein clean" hook?

19:05 technomancy: oh, for that you should just put all your stuff in the :target-path

19:05 and it will get cleaned

19:06 emezeske: I don't know about this :target-path -- what is it normally used for?

19:07 technomancy: it's a place for all generated files

19:07 .class files, jars, what have you

19:07 emezeske: this is a new lein2 thing?

19:07 technomancy: yeah

19:07 hm; that might make it harder to support both 1.x and 2.x in the same codebase

19:07 you should join #leiningen =)

19:12 mdeboard: What determines the order of the following:

19:12 &(group-by (fn [x] x) (range 50))

19:12 lazybot: ⇒ {0 [0], 32 [32], 1 [1], 33 [33], 2 [2], 34 [34], 3 [3], 35 [35], 4 [4], 36 [36], 5 [5], 37 [37], 6 [6], 38 [38], 7 [7], 39 [39], 8 [8], 40 [40], 9 [9], 41 [41], 10 [10], 42 [42], 11 [11], 43 [43], 12 [12], 44 [44], 13 [13], 45 [45], 14 [14], 46 [46], 15 [15], 47 [47]... https://refheap.com/paste/825

19:12 mdeboard: 0, 32, 1, 33, 2, 34, 3, etc.

19:12 qbg: hashcode

19:12 mdeboard: ah

19:12 &(hash 0)

19:12 lazybot: ⇒ 0

19:12 mdeboard: &(hash 32)

19:12 lazybot: ⇒ 32

19:12 mdeboard: or what

19:13 qbg: It seems to be using only the lower 5 bits due to the small number of items

19:14 mdeboard: ahhhh

19:14 interesting

19:14 qbg: Not sure what the cut off point is for persistent hashmaps

19:15 If you want it in order, use a sorted map instead

19:17 mdeboard: &(doc group-by)

19:17 lazybot: ⇒ "([f coll]); Returns a map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."

19:22 amalloy: maps aren't ordered in any way. the order of seq (or printing, which relies on seq) is arbitrary

19:23 mdeboard: They must be ordered in some way, right

19:23 qbg: implementation detail

19:23 for general purpose maps that is

19:24 amalloy: mdeboard: the map {:a 1, :b 2} has no ordering. it is a "node" with two children. neither is left or right - there's just the one labeled :a and the one labeled :b. it has to give them to you in *some* order when you ask for all of them, but that's an accident, not an integral property

19:25 mdeboard: understood

19:25 so (group-by) isn't a function to call when order is important

19:25 qbg: You can pour it into a sorted map afterwards if you want

19:25 amalloy: group-by preserves the order of the values within each key, but not the order of keys

19:26 qbg: or sort the map if you want a sorted seq of map entries

19:26 amalloy: how could it, anyway? ##(group-by even? (range 5))

19:26 lazybot: ⇒ {true [0 2 4], false [1 3]}

19:27 qbg: Usually no need to do either of those though

19:27 mdeboard: Well, just speaking in the context of the particular problem I'm working on

19:31 muhoo: i vaguely remember some function that will give me a list of all the symbols in a (or current) namespace. but i don't remember what it was

19:31 ibdknox: ,(doc ns-publics)

19:31 qbg: ,(ns-publics 'clojure.core)

19:31 clojurebot: "([ns]); Returns a map of the public intern mappings for the namespace."

19:31 {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, unchecked-inc-int #'clojure.core/unchecked-inc-int, ...}

19:31 ibdknox: lol

19:32 qbg: clojurebot feels burdened today :p

19:32 muhoo: ah, ns-publics, thanks

19:32 ,(keys (ns-publics 'clojure.core))

19:32 clojurebot: (sorted-map read-line re-pattern keyword? unchecked-inc-int ...)

19:33 qbg: See also ##(doc ns-interns)

19:33 lazybot: java.lang.SecurityException: You tripped the alarm! ns-interns is bad!

19:33 qbg: ,(doc ns-interns)

19:33 clojurebot: "([ns]); Returns a map of the intern mappings for the namespace."

19:34 qbg: Interesting lazybot behavior...

19:34 Makes sense I guess...

19:40 dnolen: pandeiro: hiredman: ibdknox: i fixed the let locals in loops bug a couple days ago

19:41 pandeiro: dnolen: awesome, thanks... unrelated: what about the gratuitous property syntax warnings?

19:41 technomancy: hah; three-star review for the Reasoned Schemer: "I guess this book is OK, but it could really be written in all of about 5 to 10 pages of text with half a page of implementation code - in Haskell."

19:43 ...with a reply from dnolen himself; awesome =D

19:43 dnolen: technomancy: heh

19:43 pandeiro: probably will get removed in the next release (whenever that is)

19:44 muhoo: hipstergrammers

19:44 alexyk: is there a shorter way to return nil or keep computing: (if (= res "skip") nil (s2l res))

19:45 hiredman: ,(doc when)

19:45 clojurebot: "([test & body]); Evaluates test. If logical true, evaluates body in an implicit do."

19:45 technomancy: alexyk: if-not?

19:45 alexyk: I want nil returned too

19:45 technomancy: ,(if-not true :a)

19:45 clojurebot: nil

19:45 hiredman: alexyk: do you not get that everthing is an expression?

19:46 alexyk: hiredman: getting it sir!

19:48 thanks for when

19:56 choffstein: Does anyone have any exampe source-code of using ring / aleph / moustache to force an https connection? I can't quite seem to figure it out. Should I just be writing a custom wrapper?

19:57 weavejester: choffstein: Usually that's handled by a redirect. If the user goes to HTTP, redirect to the HTTPS URL.

19:57 alexyk: in (fn [[[id1 ks1] [id2 ks2] res extra]] …), how do you name [id1 ks1] as a whole?

19:57 in destructuring

19:57 choffstein: weavejester: that's what I assumed -- but I can't figure out where it should go in my logic. Is that a handler wrapper to just redirect?

19:58 weavejester: choffstein: You could write it as middleware...

19:58 choffstein: weavejester: that's what I thought. Okay, I'll have at it. Thanks.

20:10 qbg: alexyk: That is a pretty complex destructuring for fn. Why not use a let inside the fn?

20:17 arohner: I'm somewhat confused by slingshot/throw+. If I do (throw+ {:foo :bar} "a message %s" "foo"), I expect to get a :message in the &throw-context that I catch. Is that correct?

20:18 my &throw-context contains only the data I threw, no :message, :cause, :environment, etc

20:26 murm: hello

20:27 any selenium/clj-webdriver gurus in the house tonight?

20:28 arohner: clojurebot: ~questions

20:28 clojurebot: Cool story bro.

20:29 mdeboard: lol

20:30 alexyk: qbg: still if I want to name a sub vector in restructuring, how would I do it?

20:30 qbg: You mean in addition to the names for its elements?

20:31 or instead of?

20:31 arohner: murm: rather than asking if you can ask a question, just ask your question. Maybe someone will answer, maybe they won't

20:32 alexyk: qbg: in addition of course

20:32 murm: arohner: I have instances where an operation fails and then my driver loses connection to the browser.

20:32 qbg: ,(let [[[id1 ks1 :as foo] [id2 ks2] res extra] [[1 2] [3 4] 5 6]] [id1 ks1 foo id2 ks2 res extra])

20:32 clojurebot: [1 2 [1 2] 3 4 ...]

20:33 murm: I'd like to be able to regain that connection to the browser and not have to start up a new driver/browser

20:33 alexyk: right, thx!

20:33 qbg: there :)

20:42 mdeboard: I'm a little confused by the wording of a 4clojure problem, http://www.4clojure.com/problem/95 ... why is `nil` considered a node?

20:43 muhoo: that's weird. in my classpath is clj-json-0.4.3.jar , but (require [clj-json.core :as json]) fails, CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: clj-json.core, compiling:(NO_SOURCE_PATH:19)

20:43 what gives?

20:43 gfredericks: forgot to quote it?

20:44 muhoo: (require ['clj-json.core :as json]) CompilerException java.lang.RuntimeException: Unable to resolve symbol: json in this context, compiling:(NO_SOURCE_PATH:22)

20:44 gfredericks: quote the whole vector

20:44 muhoo: doh, thanks

20:44 gfredericks: or equivalently, also quote the json

20:44 muhoo: Warning: *coercions* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *coercions* or change the name.

20:45 but i expected that already :-)

20:45 works

20:52 zakwilson: Ring's url-encode seems to think a space should be +. The rest of the world, last I checked thinks it should be %20. What am I missing?

20:53 technomancy: ISTR they're both acceptable

20:53 weavejester: zakwilson: It just wraps the standard URLEncoder Java class, so any quirks are carried through

20:55 zakwilson: technomancy: + doesn't seem to be treated as space by nginx, so this is at least a little problematic for the purpose of url-izing filenames to be served by a static web server.

20:55 weavejester: technomancy: The "+" isn't actually part of URL encoding - it's something of a de facto standard that grew from HTML forms.

20:55 zakwilson: weavejester: yeah, I read the source.

20:56 technomancy: huh

20:56 who has time for standards in today's modern lifestyles?

20:56 weavejester: Haha :)

20:57 When I was writing the cookie middleware for Ring, I read the specs carefully

20:57 Then, after I implemented it, I found out that no browser actually follows those specs

20:57 * technomancy still recalls the surprise he felt when he discovered HTTP header names are case-insensitive

20:57 zakwilson: Heh... well, I don't have time for stuff that doesn't work, and it appears in this case it's java.net.URLEncoder that doesn't work.

20:58 (no offense to weavejester; Ring is awesome)

20:58 weavejester: zakwilson: I'll change it for RIng 1.1 if I get a patch. I'd like to have a url-encode/decode and a form-encode/decode

20:59 And the form-encode should be able to handle maps as well...

20:59 And I'd like a pony :)

20:59 zakwilson: weavejester: are you saying I should write a URL encoder and give it to you?

20:59 * muhoo gets popcorn

21:00 weavejester: Or maybe a form-encode-params...

21:00 technomancy: delegating is the best way to get code written!

21:00 clojurebot: isn't that the secret behind your origin tory?

21:00 clojurebot: Titim gan éirí ort.

21:00 * zakwilson starts looking in to exactly what a URL encoder needs to do and contemplates shooting the author of the Java library.

21:00 technomancy: story

21:00 weavejester: zakwilson: You might be able to cheat a little

21:01 espringe: How do I concat strings in a sequence? e.g. (str (concat ["a" "b" "c"])) (except that doesn't actually work)

21:01 zakwilson: weavejester: I can get somebody else to shoot the author of the Java library?

21:01 technomancy: espringe: apply str

21:01 espringe: technomancy: thanks

21:01 weavejester: zakwilson: https://github.com/weavejester/clout/blob/master/src/clout/core.clj#L28

21:01 technomancy: np

21:02 weavejester: zakwilson: In the Java URLEncoder, spaces are erroneously encoded as +, and + is encoded as %2B

21:03 zakwilson: So combine URLEncoder with a search and replace to patch the behaviour :)

21:03 zakwilson: weavejester: so I could just string-replace + with %20 after... yeah, that.

21:03 qbg: Or you write your own

21:03 zakwilson: qbg: I don't want to.

21:03 * zakwilson stomps foot.

21:03 qbg: But its fun!

21:04 zakwilson: And you can't make me!

21:04 qbg: (once)

21:04 cemerick: The big-ball-o-mud keeps on rollin'.

21:04 zakwilson: Somebody else's problem!

21:04 qbg: There needs to be Lisp flavored ice cream

21:04 weavejester: A lot of Java libraries are programmed wrong :/

21:05 zakwilson: weavejester: really? I hadn't noticed!

21:05 * zakwilson thinks shooting's too good for the author of java.util.Date

21:06 weavejester: I'm not too fond of the HttpServlet family myself :)

21:06 Mixing cookies, sessions and raw HTTP request parsing? Ack!

21:06 CGI is a better implementation.

21:06 qbg: Java needs a @Joke annotation

21:07 weavejester: The Jetty 6 SSL API is terrible as well. Fortunately it's very much improved in Jetty 7.

21:08 And KeyStores!

21:08 Don't get me started on KeyStores :(

21:08 * weavejester rants about Java libraries.

21:08 qbg: http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html

21:09 weavejester: qbg: Noooooooooo!

21:09 qbg: But that is a different kind of brokenness

21:10 http://nooooooooooooooo.com/

21:11 weavejester: Java often reinvents the wheel, and makes it square.

21:12 zakwilson: I'm stealing that.

21:13 qbg: And in Java land, 'square' means you need to implement four classes to use it

21:15 espringe: Is there a clojure equiv to haskells 'intercalate' function? E.g. (intercalate "," ["aa" "bb" "cc"]) would return "aa,bb,cc"

21:16 arohner: espringe: clojure.string/join

21:16 espringe: arohner: perfect! Thanks

21:17 callen: wow.

21:17 they managed to rename join to intercalate?

21:17 never let mathematicians design a programming language I guess, hahahaha.

21:18 qbg: Well, if the motto of your language is "Avoid success"...

21:18 tensorpudding: there's already a function in haskell called join

21:18 Guest38809: weavejester: i was doing java the other day, and did astring.replace and wondered why it wasnt working, i forgot that unlike everything else in java, strings are immutable and therefore replace returns a new string

21:18 tensorpudding: it does something totally different

21:18 Guest38809: err

21:19 callen: tensorpudding: dare I ask?

21:19 espringe: And intercalate in haskell is a bit different in that it works on lists as opposed to strings. The type is: [a] -> [[a]] -> [a]

21:19 ivan___: i use scala a lot, but i assume immutablity there, in java i assume mutablity

21:19 qbg: &(interpose "," ["aa" "bb" "cc"])

21:19 lazybot: ⇒ ("aa" "," "bb" "," "cc")

21:21 weavejester: Yeah, in Clojure intercalate = interpose, but in Haskell strings are, IIRC, just lists of characters, rather than their own thing.

21:21 It's pretty convenient because list operations work on strings.

21:22 tensorpudding: haskell doesn't have an object-ful language that undergirds it

21:22 callen, join in haskell is a monad thing

21:22 why it's called join i don't knew, though, probably tradition

21:24 callen: tensorpudding: I have an easier time understanding monads in languages that aren't Haskell, than I do in Haskell.

21:24 I've not determined why this is the case yet.

21:24 tensorpudding: i have not seen monads outside of haskell and scheme

21:24 i don't care enough to look

21:25 weavejester: Yeah, join in Haskell is really odd

21:26 tensorpudding: it just "flattens" a layer of monad

21:27 weavejester: Yeah, I mean, it's not odd, but it's one of those functions that seems to do such wildly different things, even if underneath it's simple.

21:28 You can use it to flatten lists, for instance, but also to compose functions.

21:28 tensorpudding: it's because monads are such a generic thing

21:29 list monads are easy to understand, the function monad is less so

21:29 weavejester: tensorpudding: Yeah. They're technically very simple, but because they're so abstract, they can be difficult to understand because they often don't relate to anything concrete.

21:30 devn: where'd clojure.contrib.seq-utils go?

21:30 specifically includes?

21:30 "includes?"

21:42 mdeboard: For anonymous functions how do you indicate variable arity? e.g. #(assoc my-map :key [% & more]) sort of syntax.

21:44 Kowboy: well, poo

21:44 was trying out ibdknox's overtone example, the the site hosting the piano samples file is down

21:46 jeremyheiler: mdeboard: you use %&

21:47 mdeboard: jeremyheiler: Thanks :)

21:50 devn: Kowboy: I could host it for you if you want

21:51 Kowboy: you'll need to figure out where it puts the samples though

21:55 muhoo: Kowboy: use a differnt soundfont then?

21:59 someone explained monads to me as being "like jquery". that made sense to me. until it didn't.

22:00 ah, this, it was: http://importantshock.wordpress.com/2009/01/18/jquery-is-a-monad/

22:08 devn: Kowboy: I wouldn't worry too much about using the sampled-piano inst. Just use any old instrument.

22:09 Kowboy: also, there's the #overtone channel. It

22:09 It's not as active, but it'd be nice if it were

22:11 muhoo: monad is a word that is bigger than its name suggests

22:13 muhoo: id focus on specific kinds of monads, and even then, forget about them for the most part. read about them, but don't obsess over them. there's an old rhetorical joke in the haskell community: "brb, reading another monad tutorial"

22:14 you learn about them when you need them only because you know enough to consider them as a possibility when you actually need them.

22:18 for instance, i read a ton about monads, "got them", and then started to program actual stuff i wanted to use. it wasn't until i started toying parser combinators and thinking about quickcheck that i found them useful in practice. don't find monads. let them find you. :)

22:19 </rant>

22:20 muhoo: ^

22:21 muhoo: that, or...get obsessed with them and write another monad tutorial for clojure. both are worthwhile endeavors, just trying to underscore that it is not a pre-requisite to making substantial things that people find useful and interesting.

22:22 </second-rant>

22:23 murm: has anyone ever used htmlunit with clj-webdriver?

22:24 devn: muhoo: not yet, but ive been looking forward to parallelizing some tests with clj-webdriver

22:24 err murm*

22:25 murm: would love to get htmlunit working

22:25 I need headless

22:25 devn: murm: gist what you have?

22:25 murm: i probably can't help you honestly, leaving in a moment

22:25 but i'd like to see the germ of the idea

22:26 murm: just automating a web workflow to save time

22:26 tmciver: I'm running through an enlive tutorial (https://github.com/swannodette/enlive-tutorial/). I'm having trouble with the part that has you 'load' a file and the 'in-ns' to that file's namespace. Trouble is trying to evaluate *base-url* fails for me. Anyone have any insight into what's going on?

22:26 murm: haven't looked at the problem in a few weeks

22:26 but my issue was getting javascript turned on for the htmlunit driver, I think

22:27 devn: tmciver: could you explain how you get to the place where *base-url* is supposed to be available?

22:27 murm: I'm rolling my sleaves up now, to get back into the probelem

22:27 devn: murm: ahhh, yeah, i have no idea on that front.

22:28 murm: seems like a driver-level issue

22:28 tmciver: devn: From tutorial: user=> (load "tutorial/scrape1")

22:28 nil

22:28 user=> (in-ns 'tutorial.scrape1)

22:28 nil

22:28 tutorial.scrape1=> *base-url*

22:28 "http://news.ycombinator.com/&quot;

22:28 sorry for spamming.

22:28 devn: tmciver: no prob this time, but in the future gists are nice, or inline it

22:28 murm: yea, I'm not sure if htmlunit implements all the same options that the other drivers do

22:29 devn: murm: htmlunit is faster, but yeah, i think it leaves out the kitchen sink on purpose

22:29 tmciver: Not sure if this tutorial is old but I don't usually see 'load' followed by 'in-ns'; usually one uses use.

22:30 murm: not being able to turn on the javascript is a showstopper though

22:30 devn: murm: are you peeking at source

22:30 tmciver: Actually, it looks like the tutorial is a little old.

22:30 devn: tmciver: what editor do you use?

22:30 tmciver: it is a little old...

22:30 murm: devn: I went spulunking... no luck

22:30 just confused me

22:31 tmciver: I use emacs, but this tutorial includes code so I just fire up 'lein repl' and run that code there.

22:31 devn: murm: it seems fairly straightforward in some ways. im just browsing, but the functions for things like "refresh", "switch-to-window", etc. are pretty common

22:31 tmciver: do you ever use clojure-jack-in?

22:31 murm: devn: yea, I can use those fairly effectively

22:32 tmciver: devn: Yes, I actually usually do, I was trying to follow the tutorial to the letter.

22:32 devn: maybe I shouldn't . . .

22:32 devn: clj-webdriver is really a nice library

22:32 * devn jealous

22:33 devn: tmciver: i could try out your exact steps if you gist them

22:34 tmciver: it sounds like you lein deps, lein repl, (load "foo/bar.clj"), (in-ns 'foo.bar), *base-url*

22:34 tmciver: devn: yes, that's it. It's given at the link I gave for the tutorial under the heading: "Your First Scrape with Enlive – Hacker News"

22:35 murm: oooh, check out clj-webdriver-taxi: https://github.com/semperos/clj-webdriver/wiki/Introduction%3A-Taxi

22:35 devn: tmciver: it works for me

22:35 tmciver: devn: *base-url* resolves? Hmmm.

22:35 devn: tmciver: yeah, no problem here

22:36 tmciver: devn: I'll try again. Thanks for the verification.

22:36 tardo: what's the website with the clojure lessons/challenges

22:36 i can't find it anywhere

22:36 Raynes: 4clojure.org

22:36 tardo: tyvm

22:36 Raynes: yavw

22:36 devn: tmciver: git clone url-for-enlive-tutorial, cd enlive-tutorial, lein deps, lein repl, (load "tutorial/scrape1"), (in-ns 'tutorial.scrape1), *base-url* => "http://news.ycombinator.com/&quot;

22:36 taufiq1: does gen-class let you add java annotations? need to interop with an existing library

22:37 devn: Raynes: you swooped in there for the kill. well done, sir.

22:37 * Raynes slicks his hair back

22:37 devn: taufiq1: http://kotka.de/blog/2010/02/gen-class_how_it_works_and_how_to_use_it.html

22:38 tmciver: devn: ran through it again and it works. Don't know what I did wrong but thanks again!

22:38 devn: tmciver: no problem man. have fun! :)

22:40 taufiq1: devn: thanks, i've been through that page, perhaps I missed the mention of adding annotations but I haven't seen any. Is it done as part of the metadata?

22:40 devn: taufiq1: honestly I've never done it, I just had that link in my bag of gen-class tricks.

22:41 taufiq1: could you speak in a more general sense about the problem? you seem to want annotations, what got you there?

22:41 taufiq1: Need to interoperate with an existing java library that looks for specific method annotations

22:41 I can probably make do with using deftype and its annotation support instead

22:42 devn: taufiq1: yeah i think that's where i was headed next

22:42 taufiq1: deftype seems like the way to go

22:42 taufiq1: haven't used it before, always good to learn something new

22:43 devn: taufiq1: here's an old thread, but it looks pretty relevant to your issue: http://groups.google.com/group/clojure/browse_thread/thread/d2128e1505c0c117

22:43 tardo: would you compare lists to arrays in other languages, or is there a notable difference

22:43 taufiq1: mm, that example looks good, thanks again devn

22:43 devn: taufiq1: no problem

22:44 tardo: there is a notable difference. http://en.wikipedia.org/wiki/Linked_list#Linked_lists_vs._dynamic_arrays

22:46 tardo: devn: oh i see, i had to write linked lists object classes back in highschool lol, just didnt realize that's what '(1 2 3 4) was

22:46 ty

22:46 devn: tardo: it's not === a clojure '(1 2 3)

22:46 but in general the above link draws the distinction

22:47 tardo: kk

22:48 devn: tardo: check out http://clojure.org/data_structures

22:48 muhoo: devn: thanks i won't obsess over stuff i don't understand and probably don't need; there's plenty still that i don't understand and definitely do need

22:49 hmm, where was i in 2010 when everyone was writing blogs about clojure?

22:49 devn: muhoo: it's fun. clojure is a great opportunity to learn a ton, but my experience has been to pick my battles or it will be overwhelming. sometimes i devote a weekend to thinking about something specific, other times i just make stuff for fun. it's been a balancing act for me.

22:49 muhoo: they're still writing them! :)

22:49 muhoo: planet.clojure.in

22:50 disclojure.org

22:50 muhoo: seems to me like 2010 was Peak Clojure Blog

22:50 devn: muhoo: scrape all of the clojure RSS feeds and prove it to me. :)

22:50 muhoo: now, that'd be an interesting program

22:50 devn: muhoo: if you feel that way it underscores that "We Need Your Help, Soldier."

22:51 write about clojure on your blog :)

22:51 muhoo: no, i meant, it'd be interesting to write a clojure program that scrapes all the clojure blog entries and comes up with a graph of # of posts by year

22:52 to prove or disprove my conjecture about Peak Clojure Blog

22:52 devn: muhoo: it's not hard! check out webmine for clojure

22:53 tardo: read about clojure collections, then read about list, vector, array

22:53 muhoo: baahaaa

22:53 i found a blog entry about using webmine.... from 2010 http://www.dzone.com/links/mining_the_web_withclojure.html

22:53 devn: :)

22:53 tardo: devn: aye aye!

22:53 devn: i think webmine is being used to power prizmatic, bradford cross's startup

22:53 i forked it to preserve it for posterity

22:54 i mean, it is a very small tool in their toolbelt, there are a lot of really interesting algorithms going on behind the scenes

22:54 but even still, RSS scraping and so on is built-in

22:54 (to webmine i mean)

22:56 muhoo: i won't disagree with you about 2010 being a big year. but i think it's far from the max. in the time since then the number of unblogged contributions has grown exponentially

22:57 brehaut: also a bunch of the bloggers who were prolific in 2010 spent 2011 writing books

22:58 devn: or at least it seems that way to me. there may well be fewer blog posts, but at the same time there are more conferences, and more people adopting it. perhaps the barrier for getting your blog post talked about on an aggregator has grown

22:58 muhoo: wow, richard gabriel-- who gave the world xemacs-- presenting at clojure west

22:58 devn: sort of a sign of maturity

22:58 yeah im still pissed i cant make it to clojure/west, but i need to go sit in the carribean and do nothing for a week or two

22:58 hopefully euroclojure will take me

22:58 Raynes: muhoo: That's a good thing?

22:58 muhoo: devn: a better metric is the quantity and quality of code, which i guess scraping github might facilitate measuring

22:58 Raynes: :p

22:59 devn: muhoo: my gut tells me all code has gotten better, period.

22:59 or at least, the average for quality has been raised.

22:59 muhoo: Raynes: it's an odd thing. totally unexpected. old-skool lisper, worked with rms at mit, etc.

22:59 clojurebot: Pardon?

23:00 devn: muhoo: it's weird but also not at all weird. unix is simple and yet i see people say things like: "i use heroku because it's easy. i'm not a command line masochist."

23:01 there is a similar theme with clojure. it is simple, but the gut reaction for many is to run around yelling fire about parens or some other equally funny aspect.

23:02 reminds me of "worse is better"

23:02 which, lol, is written by...

23:02 Richard Gabriel: http://www.jwz.org/doc/worse-is-better.html

23:03 muhoo: yep

23:05 levi: He also wrote a book on software patterns.

23:05 http://dreamsongs.net/Files/PatternsOfSoftware.pdf

23:06 muhoo: hahaha, "tough man to make a tender chicken" is frank perdue http://www.youtube.com/watch?v=uN37i9qr0zY

23:06 new jersey joke, circa 1970s-1980s

23:12 levi: His Patterns of Software book is interesting, as it's more of a set of essays applying Christopher Alexander's work on design patterns in architecture to the crafting of software than it is a catalog of patterns like the GOF book.

Logging service provided by n01se.net