#clojure log - Apr 11 2011

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

0:03 amalloy: mec: clojure-mode does that already

0:04 mec: i mean for your lazy-loop too

0:04 amalloy: mec: aha! funny you should ask. when i wrote lazy-loop i added a customizable variable to clojure-mode for just that reason

0:05 try M-x customize-variable clojure-defun-indents. if it doesn't exist, you need a newer version of clojure-mode

0:05 mec: nope, i've got an old one

0:06 amalloy: it's only been around for like two weeks, so that's unsurprising

0:24 mec: ,(clojure.lang.PersistentQueue. nil 0 nil nil)

0:24 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class clojure.lang.PersistentQueue

0:24 mec: how come it says that even though thats exaclty how EMPTY is defined

0:25 amalloy: mec: either (a) the constructor is non-public, or (b) you're wrong about EMPTY being defined that way

0:26 mec: ah ya it isnt public

0:26 amalloy: mec: anyway i doubt the new versions of clojure-mode are in elpa, but you can pull from github and customize indentation to your heart's content

0:26 * amalloy is off to bed

0:26 mec: night

3:22 tsdh: Does anyone have a link to one of the various alternative definitions of `all' and `any' which are equivalent to reducing `and' / `or' through a sequence, just with short-cirquit behavior?

3:35 angerman: tsdh: stackoverflow has some: http://stackoverflow.com/questions/5531964/non-macro-versions-of-clojure-and-and-or

3:40 tsdh: angerman: Great, thanks. Oh, and is seems that they've already hit clojure.core as `any-pred' and `every-pred' (in 1.3).

3:43 mreynolds: I have a vector [0 1 2 3 4 5] and I want to loop through the vector, pulling off pairs of numbers. I'm wracking my brain, is there a way to do this?

3:50 raek: mreynolds: which pairs are you interested in? (0 1) (1 2) (2 3) ...?

3:50 Totramon: mreynolds: what do you mean with pairs

3:50 heh, that

3:50 mreynolds: I'd like to have [0 1] [2 3], etc

3:50 Really, I want to map them to variables and use them

3:50 Totramon: I think partition does this

3:50 mreynolds: [key type], etc

3:51 Looking

3:51 raek: ,(partition 2 [0 1 2 3 4 5])

3:51 clojurebot: ((0 1) (2 3) (4 5))

3:51 Totramon: into {} (partition..

3:51 mreynolds: hah!

3:51 Thank you so much

3:51 I've spent far to long looking for that.

3:51 Totramon: :)

3:52 nevermind that into, was thinking of something different

3:52 mreynolds: no worries, thanks so much!

3:52 raek: ,(->> (range 6) (partition 2) (map vec) (into {}))

3:52 clojurebot: {0 1, 2 3, 4 5}

3:53 raek: ,(->> (range 6) (partition 2) (into {}))

3:53 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Map$Entry

3:53 ejackson: Morning, Clojurati.

3:53 raek: arbitrary dequences do not work as map entries...

3:53 *sequences

3:54 Totramon: must have been with 2-element vectors only then

3:54 thanks

3:55 is that ->> considered good style btw?

3:55 first time I saw it

3:57 mreynolds: Thanks all, night

3:57 raek: I personally think that it maybe makes that code snippet a bit easier to read (but certainly simpler to write on multiple lines) than just (into {} (map vec (partition 2 (range 6))))

3:59 but maybe the gain is larger for ->, since without that one the nested expressions tend to "split" the outer ones in half and separate the halves from each other

4:17 markoman: is there a way to change "string-key" to :string-key ?

4:19 or ":string-key" to :string-key as well

4:26 ,(symbol (str ":" "key"))

4:26 clojurebot: :key

4:29 markoman: but its not same?

4:29 ,(= :key (symbol (str ":" "key")))

4:29 clojurebot: false

4:34 raek: markoman: ##(keyword "string-key")

4:34 sexpbot: ⟹ :string-key

4:35 raek: markoman: symbols and keywords are different things...

4:35 but clojure does currently allow you to construct symbols starting with a : (which is not recommended to do, as you can see)

4:36 markoman: i see

4:36 raek: also:

4:36 ,(doc clojure.walk/stringify-keys)

4:37 clojurebot: "([m]); Recursively transforms all map keys from keywords to strings."

4:38 markoman: good to know. so there are symbols, names and keywords. something else?

4:38 raek: what are names?

4:38 markoman: oh, i think of (name :string-key)

4:39 raek: 'name' is a function that takes a symbol, keyword or (since 1.2) a string and returns a string

4:40 ,(map name [:foo 'foo "foo"])

4:40 clojurebot: ("foo" "foo" "foo")

4:40 raek: ,(map class [:foo 'foo "foo"])

4:40 clojurebot: (clojure.lang.Keyword clojure.lang.Symbol java.lang.String)

4:41 raek: the atomic data types in clojure are: numbers (various kinds), nil, booleans, strings, characters, regexes, symbols and keywords

4:42 AWizzArd: raek: atomic data types?

4:42 Those sound like literals.

4:43 raek: as in, non-compound

4:43 AWizzArd: But Strings seem to be collections of chars.

4:43 raek: or non-aggregate

4:44 well, the string "foo" is distinct from [\f \o \o] and (\f \o \o)

4:45 ok, atomic in the sense "indivisible" might be slightly inaccurate here

4:47 markoman: ok. fair enough to start with. then my next step is to find keys from map like {:key1 {} :key2 {} ...} -> [key1 key2 ...]. I can map keyword, but how to collect keywords only from first map?

4:48 loops and iterations are still something im not familiar with clojure

4:48 raek: markoman: you want to do something for each key-value pair?

4:49 markoman: no, just to get string presentation of keys in list

4:49 actually resut would be ["key1" "key2" ... ]

4:50 raek: terminology: key = whay you look up from when using a map; keyword = a kind of value

4:50 ,(map name (keys {:a 1, :b 2}))

4:50 clojurebot: ("a" "b")

4:51 markoman: :key = keyword key?

4:51 raek: a keyword used as a key, yes

4:51 morphling: ,(keyword "key")

4:51 clojurebot: :key

4:52 markoman: right.

4:53 raek: markoman: regarding loops and iterations: in functional programming it makes more sense to think of what you want the resulting value to look like, rather than the mechanism for how to do something for each thing

4:54 {"this is a string used as a key" "this is a string used as a value", :keyword-key :keyword-value, 'symbol-key 'symbol-value}

4:56 markoman: yeah, the result is what im interested at the end. i can already see most things can be done with map what im used to do with foreach

5:17 hmh... I have (def default-data {}) and I want to use it on other namespace but copy it, using as a template, not modify

5:18 similar to: (:require default-data :as-copy data)

5:20 raek: if you want to access it using another name, you can do this (:use [the-ns :only [default-data] :rename {default-data some-other-name}])

5:20 then, 'some-other-name' will be the name for that var in the namespace

5:21 markoman: and I can modify some other name and it wont change original default data?

5:21 raek: also, vars (the things def make) are made to be constant

5:21 markoman: ah, I see

5:21 raek: you should only change the root value of a var when fixing bugs

5:22 in this case, changing the value of #the-ns/default-data affects the other namespace too

5:23 (where some-other-name is the name for #the-ns/default-data)

5:23 sorry, it should have been #'foo, not #foo

5:26 markoman: does this mean :rename makes a copy of default data and when im changing renames map, it doesnt change original?

5:27 raek: no, no copies are made

5:27 you simply introduce an alias to the var

5:28 however, there is no "simple" way of setting a var in another namespace

5:28 markoman: ok. but Im going to need to alter the map on different namespaces. id like to use original as a template only

5:29 raek: you can use (alter-var-root ..), but it takes the var object itself, rather the name of it

5:31 then, I'd suggest doing something like (ns the-second-ns (:use [the-ns :only [default-data]])) (def data (assoc default-data ...))

5:31 markoman: how about using atoms in this case?

5:32 raek: in what namespace is the changable thing going to live?

5:32 an atom would be good, since then you are explicit about what can change

5:33 (in constrast to vars, which are supposed to not change, but can be anyway for fixes)

5:37 markoman: in qtypes ns I have: (def default-qtype-data {:create (fn [args]) :show (fn [args])}) and qtypes.checkbox ns I want to use default, but probably change :show function only. having a few default templates would reduce duplicate coding

5:39 so Im thinking to (def data <- default-data) and then alter :show part

5:39 raek: then (:use [qtypes :only [default-data]]) to get access to the defaults, and then build the new map with (def data (assoc default-data :show (fn ...)))

5:40 don't alter.

5:40 it's more ideomatic to construct the complete value, and then bind that

5:40 markoman: the return of assoc, it contains all defaullt-data, not only :show part?

5:41 raek: yes

5:41 and it doesn't change the original (since datastructures are immutable)

5:41 ,(assoc {:a 1, :b 2, :c 3} :b :something-else)

5:41 clojurebot: {:a 1, :b :something-else, :c 3}

5:42 raek: in the beginning, it might be easier to think of def as "assign once only"

5:43 markoman: then its perfect. but of course, there are a lot of other parts too that changes. so after I make assoc :show, is there a problem I make again (def data (assoc data :list ...)

5:43 clojurebot: 'Sea, mhuise.

5:43 raek: you can "update" multiple keys with assoc

5:44 (def data (assoc default-data :show ..., :list ..., :foo ...))

5:44 markoman: because at the end, when Im using checkbox/data it should contain final composition based on default-data

5:44 raek: you should do all the composing inside one def form

5:45 and clojure provides many functions for making these kind of things easy

5:45 you can also make helper funktions if the expression become too big

5:46 markoman: ok, then its just structuring parts clearly

5:48 I think this is enough for now, thanks :)

6:18 fliebel: What happens when I do ##(recur) at the top level?

6:18 sexpbot: Execution Timed Out!

6:18 fliebel: I think any repl does that in a thread, so that would recur to that callable.

6:32 GeoffSK: i am having some fnparse (beginner) problems, can anyone help with http://pastebin.com/ex9BbFZ1

6:34 ready to run version: http://pastebin.com/dvA2yQig

6:46 no_mind: is there a trie implementation in clojure ?

6:49 fliebel: no_mind: I don't know, but you might be able to bend the rules of a finger-tree to do that.

7:29 no_mind: one question which has to do more with lisp than clojure per se. When should I use macro instead of a function ?

7:32 ogonzalez: no_mind, I'm a complete newbie but maybe when you want to alter evaluation order, alter normal language semantics in a concrete part of your program, generate some boilerplate...

7:32 fliebel: no_mind: When you need to define new syntax. Macroes are magic, so reserve them for magic. Do the real work with functions.

7:33 no_mind: thnxs fliebel

7:34 raek: (inc fliebel)

7:47 TimMc: no_mind: Remember, you can still define DSLs using functions.

8:08 raek: "Domain Specific Values"

8:14 how widely accepted is the foo->bar naming convention?

9:28 TimMc: raek: I use that all the time, including <-foo and ->bar multimethods. :-P

9:29 s/<-foo and //

10:56 * ejackson listens to the crickets

11:05 amac: anyone know of a good contrib.error-kit usage example?

11:26 carllerche: Is there a way to use defrecord w/ a one off protocol instead of defining the protocol separately?

11:37 dnolen: carllerche: nope.

11:43 carllerche: dnolen: this is kind of what i'm trying to do, what would be the idiomatic way to do it? https://gist.github.com/3be71ab4c67754f522e8

11:43 dnolen: callerche: looks fine, but you have to define a protocol.

11:44 callerche: it's only 2 more lines of code, so it's not exactly tedious :)

11:45 carllerche: i guess if i really cared, i could make a macro

11:46 amalloy: carllerche: i don't understand the goal. why would you want to define a protocol that nobody has access to?

11:46 carllerche: amalloy: the goal is that I will need api-key and host in every single function to talk w/ campfire, so i'm trying to avoid code to extract that information from every function

11:47 i'm sure there is a much better way to do this :P

11:48 amalloy: carllerche: (defmulti get-api-credentials [url] host-identifying-function)?

11:49 since all you really want is a flexible way to get credentials

11:50 carllerche: how would I use it?

11:50 also, i'm thinking that (defn configure ) might be able to return a function that does the actual HTTP requests

11:50 amalloy: well, write a host-identifying-function that looks at a url like "www.campfire.com" and says, "oho, that's campfire"

11:51 then (defmethod get-api-credentials ["campfire"] (GET whatever))

11:52 seems a lot cleaner than creating a bunch of actually-unrelated Record classes that happen to have similar behavior

11:52 carllerche: ah... hmmm

12:26 mabes: is it possible to set a static field onto record classes? I would like to manually set serialVersionUID to avoid some [de]serialization issues I'm running into (adding a field to the record, etc..)

12:52 amalloy: mabes: i don't think so; is it feasible to use clojure's pr-str and and read for serialization, instead of java's?

12:54 mabes: amalloy: not in this case.. records don't support prn-str serialzation natively (although you can add that like defrecord2 does), but the bigger issue is that these records contain java objects. So, I'm already living in java land. :(

12:54 amalloy: alas

13:03 angerman: wow. QT takes ages to compile

13:03 (trying to compile phantomjs)

13:03 Raynes: You haven't compiled until you've compiled GHC.

13:04 angerman: Raynes: that might be, I guess I just went with haskell platform.

13:05 ejackson: Raynes: pish, you haven't compiled till you've completed LFS.

13:07 technomancy: epihpany is the most terrifying thing I've ever compiled. it depends on a full mozilla build, a full GNOME build, *and* webkit.

13:08 ejackson: :)

13:08 angerman: this is so rediculous. It should at least detect that I'm on os x and use webkit as a drop-in replacement :/

13:08 QT feels viral on each encouter :(

13:23 amac: ,(get {:a 1} :a (/ 1 0))

13:23 clojurebot: java.lang.ArithmeticException: Divide by zero

13:24 amac: is there a lazy form of get that doesn't evaluate the default unless needed?

13:26 lazy1: ,(or (:a {:a 1}) (/ 1 0))

13:26 clojurebot: 1

13:26 lazy1: or does short-circuit

13:26 amac: aaaaaaaaaah, perfect

13:33 raek: ,(if-let [[_ v] (find {:a 1} :a)] v (/ 1 0))

13:33 clojurebot: 1

13:33 raek: amac: ^ in case you need to be "nil transparent"

13:34 lazy1: ,(:a nil)

13:34 clojurebot: nil

13:34 lazy1: keywords are nil transparent as well

13:35 The other way around will throw -> (nil :a)

13:59 carllerche: is it possible to get readline(ish) support in the emacs clojure repl?

14:10 raek: lazy1: my idea when I used the word "nil transparent" was that a nil value doesn't count as no value

14:11 ,(or (:a {:a 1}) (/ 1 0))

14:11 clojurebot: 1

14:11 raek: ,(or ({nil 1} nil) (/ 1 0))

14:11 clojurebot: 1

14:12 raek: hrm. nevermind :)

14:12 ataggart: ,(or ({:a nil} :a) (/ 1 0))

14:12 clojurebot: java.lang.ArithmeticException: Divide by zero

14:12 ataggart: is what I think you meant

14:12 raek: that's right

14:23 TimMc: OK, I'm writing a ray tracer, and I'd like to have multiple threads tossing pixels into a BufferedImage as I repeatedly repaint it to the canvas.

14:24 Since BufferedImage is ultimately backed by an array, is it safe to write to it from multiple threads simultaneously?

14:25 ohpauleez: TimMc: sure, using it in ref

14:26 TimMc: ohpauleez: What do refs have to do with it?

14:26 This is a Java array.

14:28 ohpauleez: TimMc: You're writing the ray tracer in Clojure, that is multithreaded and you want the threads to update BufferedImage concurrently

14:28 I don't know if BufferedImage is thread-safe

14:29 so I was suggesting you use a ref and dosync, to do the concurrent updates from the threads

14:29 TimMc: Bleh, too much overhead.

14:30 What I want to know is whether it is thread-safe, given that each thread will be writing to its own set of pixels.

14:31 If it isn't thread-safe I'll use getWritableTile or something.

14:31 ohpauleez: TimMc: might be useful: http://stackoverflow.com/questions/2857332/safe-to-update-separate-regions-of-a-bufferedimage-in-separate-threads

14:32 cemerick: TimMc: Rasters are basically arrays; Image subclasses have graphics contexts associated with accelerations pipelines and all sorts of other dark magic that varies from platform to platform. I wouldn't touch the latter from multiple threads.

14:33 TimMc: brb

14:34 cemerick: FWIW, you can easily get a WritableRaster, blit to that from N threads without a problem, then create a BufferedImage from the completed result.

14:38 TimMc: cemerick: BufferedImage has a getWritableRaster -- that's what I would use.

14:38 What the hell, I'll just WriteSomeDamnCode.

14:39 As for the Clojure side of things... what should I use for the 4 or so worker threads?

14:41 ohpauleez: TimMc: Futures, perhaps?

14:41 or just use threads

14:41 TimMc: I've never worked with futures or agents, so I don't have a feel yet for their use patterns.

14:42 ohpauleez: if all you need are threads, Futures are appropriate

14:48 phenom_: I'm getting some significant thread blocking when running code that uses multimethods .. any ideas on how I can change around my code to avoid this?

14:50 cemerick: phenom_: it's pretty unlikely that multimethods are the cause, unless you are modifying them constantly

15:35 spewn: I wonder if the Irssi users in this channel might find this useful: https://github.com/0/irssi-rainbow-parens

15:47 TimMc: Well, futures seem to work just fine.

15:49 rumbold: hi. i'm new to clojure. what are some ides with good clojure support?

15:50 nickik: the big java ones + emacs + vim

15:50 ohpauleez: TimMc: Glad to hear it!

15:50 rumbold: i started learning emacs a bit, but im not sure if i really want to

15:51 TimMc: rumbold: I learned Emacs to work with Clojure -- it was worth the learning curve.

15:51 (Third time I tried. :-P)

15:51 ataggart: rumbold: what IDEs are you familiar with?

15:51 TimMc: ohpauleez: Now I have progressive rendering in my ray tracer!

15:51 rumbold: visual studio mostly :p

15:51 ohpauleez: TimMc: Nice!

15:51 rumbold: what's prograssive rendering?

15:51 *e

15:52 TimMc: rumbold: Instead of rendering the whole scene off-screen and then dumping the whole thing into a window when it is done, I'm updating the canvas line by line.

15:53 rumbold: ah

15:53 why not pixel by pixel?

15:53 TimMc: I'm rendering the scene pixel by pixel into a BufferedImage, then repainting the entire BufferedImage onto the canvas several times per second.

15:54 It ends up being more or less chunk by chunk, really.

15:54 rumbold: ah

15:54 TimMc: https://github.com/timmc/CS4300-hw6/tree/master/src/hw6

15:55 rumbold: i wanna write a little game in clojure. what are some good libraries for that? ill probably use penumbra for graphics, i guess. might need something for physics. although it might be simple enough to just write it myself

15:55 TimMc: ^ core.clj does all the threads and GUI stuff, tracer.clj actually handles rendering.

15:57 I should actually start writing the usage instructions soon. >_<

15:58 rumbold: what does ^ do?

15:58 some kinda java reference?

15:59 mduerksen: rumbold: yes, it's a type hint

15:59 ohpauleez: rumbold: It's used to type hint and also to attach metadata to something

16:00 rumbold: Type hints are used in Java interop and when you compile your class

16:02 rumbold: is clojurebox a good choice?

16:02 oh the website doesnt even work anymore

16:04 jweiss: i see there's no dissoc-in - is there a simple way to implement?

16:07 ohpauleez: jweiss: (dissoc m :a :d)

16:07 given something like: (def m {:a 1 :b {:c 3 :d 4}})

16:07 should work

16:07 jweiss: hm that is not how i interpreted the doc but will try

16:08 ,(dissoc {:a 1 :b {:c 3 :d 4}} :a :d)

16:08 clojurebot: {:b {:c 3, :d 4}}

16:08 jweiss: hm no

16:08 ohpauleez: ohhh nvm, I think you're right, I was misunderstanding

16:09 ataggart: jweiss: you weren't the only one

16:09 hmm, no it seems it doesn't

16:10 mt

16:10 ohpauleez: jweiss: http://clojuredocs.org/clojure_contrib/clojure.contrib.core/dissoc-in

16:11 choffstein: hey all! is there a good library for sending e-mails (like Ruby's ActionMailer)?

16:11 jweiss: ohpauleez: ah thanks, never woulda thought to look in contrib since update-in and assoc-in are in core

16:12 ohpauleez: choffstein: Take a look at clj-mail

16:12 choffstein: thanks :)

16:12 ohpauleez: choffstein: Welcome: https://github.com/MayDaniel/Clj-Mail

16:12 choffstein: that's perfect!

16:12 ohpauleez: no idea if that's what you need

16:12 awesome

16:16 amalloy: jweiss: it's easy to do with update-in: ##(update-in {:a {:b {:c 1}}} [:a :b] dissoc :c)

16:16 sexpbot: ⟹ {:a {:b {}}}

16:18 drewr: choffstein: I'm biased, but I prefer http://github.com/drewr/postal for sending

16:18 jweiss: amalloy: ahh duh. from the doc it sounded like it can only update the value, but you just went one key higher up the structure :)

16:18 choffstein: just a bit biased, eh? ;) Thanks, i'll check it out too

16:19 ohpauleez: amalloy: ah right, that's better

16:19 I actually have used that befor

16:20 drewr: choffstein: sane defaults, sends via sendmail or smtp, in production use at an email company, etc.

16:20 amalloy: i'm surprised dissoc-in isn't implemented using update-in

16:20 ohpauleez: I am too actually

16:20 and why it's using a hard recursion call like that

16:20 amalloy: maybe it doesn't work for a top-level key

16:20 &(update-in {:a 1} [] dissoc :a)

16:20 sexpbot: ⟹ {nil nil, :a 1}

16:21 ohpauleez: good thinking

16:25 mec: anyone else get an error trying to run the astar function from Joy of Clojure?

16:28 amalloy: ~source update-in

16:28 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: replaceAl for class java.lang.String>

16:28 amalloy: hiredman: ^?

16:28 $source update-in

16:28 sexpbot: update-in is http://is.gd/DuMg4s

16:29 nickik: I split up my little webapp into 5 namespaces (from one) now I cant do interactive development anymore. When it was in one namespace I could just recomile and hit F5 know I have to restart the webserver (lein ring server). Anybody knows that problem?

16:42 mec: im getting an exception that doesnt reference the file the function is in at all, how could i narrow it down?

16:44 dnolen: mec: what is the exception?

16:45 mec: lazyseq cant be cast to comparable

16:46 amalloy: mec: you have a sorted-{set,map} of lazy-seqs, perhaps?

16:48 ohpauleez: nickik: Why can't you do interactive development anymore? You just need to reload all the namespaces

16:49 mec: amalloy: sorted-set, but I wrapped the lazy-seq in a vec and it still happens

16:49 nickik: ohpauleez: I do but it doesn't help

16:53 choffstein: is there a way to set the encoding type with hiccup's form-to?

16:53 mec: did lazy-seqs implement comparable at some point in the past?

16:53 amalloy: i doubt it

16:54 (the above to mec, not to choffstein. no idea re choffstein)

16:54 mec: how could lazy-seqs implement comparable? they can't even know whether they have any elements

16:55 mec: its code straight from joy of clojure, im at a loss here

16:59 amalloy: mec: the A* stuff you mentioned earlier?

16:59 mec: ya

16:59 it looks like the error is coming from (into (sorted-set) (lazy-seq of vectors)) which doesnt make sense

17:01 amalloy: vectors might implement Comparable by comparing elements pairwise, and if one of them has a lazy-seq as an element...?

17:03 mec: ah thats it

17:18 devn: Is there a limit on how long a function name can be?

17:19 amalloy: devn: don't think so

17:19 mec: doesnt look like it

17:20 amalloy: you can have symbols of at least 10k characters, and functions can be associated with any symbol, so...

17:22 devn: how do you figure 10k characters?

17:24 wtetzner: ,(->> (repeat \a) (take 10000) (reduce str) symbol name count)

17:24 clojurebot: 10000

17:26 amalloy: devn: cause i tried it once

17:26 like that, tahnks wtetzner

17:27 Chousuke: prefer apply str instead of reduce str though :P

17:27 amalloy: yeah

17:27 mec: gets laggy at 10000000 :D

17:28 dnolen: so noone's done anything involving decision diagrams in Clojure, eh?

17:28 amalloy: dnolen: like finite state machines, or something more vague?

17:29 dnolen: amalloy: more binary decision diagrams, multi-valued decision diagrams.

17:32 amalloy: not unrelated tho, been looking at how Standard ML aggressively optimizes pattern matching. I've read some implementations use tree automata.

17:32 amalloy: all a big mystery to me, i'm afraid. i keep meaning to write a less-parser-looking NFA/PDA library

17:33 but tree automata and multi-valued decision diagrams are not in my repertoire

17:34 schlechtv: Is there an idiomatic way to solve the following problem: partition a seq when the difference between the first and the last elee

17:34 element of the partition is greater than or equal to a given value

17:36 i.e. for a difference value of 4: (1 2 3 4 5 6 7 7 7 7 7 7 9 10) -> ((1 2 3 4 5) (6 7 7 7 7 7 7 9 10))

17:36 amalloy: interesting problem. it seems like a combination of iterate and take-while

17:37 maybe iterate and split-with

17:38 schlechtv: hm, didn"t think about split-with yet... I kind got stuck trying to solve it with partition-by

17:39 amalloy: schlechtv: i suspect that's a dead end

17:39 Chousuke: sounds a bit tricky

17:39 amalloy: was my first instinct too but i don't think you can mold it into the right shape for partition-by

17:42 $findfn -4 4

17:42 sexpbot: [clojure.core/unchecked-negate clojure.core/-]

17:42 amalloy: ugh where is abs

17:42 mec: Math/abs

17:42 schlechtv: me neither ... I already hacked away looping through the seq, but it grew uglied by the minute ..

17:42 ohpauleez: amalloy: ^ (Math/abs is WAY faster than contrib.math)

17:48 amalloy: schlechtv: gisting up something that seems to work in a sec

17:50 https://gist.github.com/8ef871f0d800e6e692db needs to be wrapped up in a function, but that's the logic

17:50 * amalloy spent more $$%#@ time figuring out whether to use <= or >= than he did writing the sequence code

17:51 schlechtv: amalloy, I'm awestruck, trying to even understand how that works

17:53 amalloy, seems I *will* get some sleep tonite then :-) Thanks a lot!

17:54 amalloy: schlechtv: i write code like this often enough that i have some tools to make it a little less primitive, but i wanted something that works with no dependencies outside of clojure.core

17:54 schlechtv: welcome

17:55 schlechtv: amalloy, fair enough ... I need to wrap my head around the clj standard lib first anyway and your solution is great both for its practical and educational benefits :)

17:55 amalloy: schlechtv: it might well be cleaner to write it directly as a lazy-seq. exercise for the reader

17:56 schlechtv: will do!

18:12 choffstein: Any idea why I keep losing data when I try to create a file uploading using ring.middleware.multipart-params? The temp file created is correct, but the 'filesize' reported is not.

18:12 Glass_Arm: faggots

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 d

18:12 clojurebot: destructuring is http://clojure.org/special_forms#let

18:12 devn: ...

18:24 Did that just happen?

18:25 ohpauleez: Wow

18:27 amalloy: clojurebot: way to show him the door

18:27 clojurebot: I'm sorry, amalloy. I'm afraid I can't do that.

18:34 choffstein: is there a way to slurp in files in binary mode?

18:41 technomancy: rebinding *out* to *err* is the simplest way to println to stderr, right? (other than invoking methods on *err* directly)

18:41 devn: choffstein: clojure.contrib.io.to-byte-array

18:43 hiredman: technomancy: some common things that try to print errors (like printStackTrace) expect a printwriter, and I think *out* isn't always a printwriter

18:45 technomancy: yeah, I'm thinking just a simple println

18:45 OTOH, the JVM is already so anti-unix maybe it's not worth bothering to make the distinction.

19:39 TimMc: clojurebot: <3

19:39 clojurebot: <3 is </3

19:39 TimMc: clojurebot: You're just playing hard-to-get.

19:39 clojurebot: I don't understand.

19:44 Raynes: amalloy: I think that was our first spam.

19:50 amalloy: what?

19:50 clojurebot: What is meta

19:51 amalloy: the guy spamming "d"? we've had spam in here before

19:51 clojurebot: meta?

19:51 clojurebot: ⟹ "Returns the metadata of obj, returns nil if there is no metadata."

19:57 WuHoUnited: (meta clojurebot)

19:58 amalloy: clojurebot: meta is meta

19:58 clojurebot: Ok.

20:30 semperos: brehaut: ping

20:30 brehaut: semperos: pong

20:31 semperos: question on ne (what else)

20:31 brehaut: shoot

20:31 semperos: I have code that throws a custom exception

20:31 class org.openqa.selenium.NoSuchElementException

20:31 when this gets thrown and returned to the client, the client throws an XML error

20:32 Attribute name "org.openqa.selenium.NoSuchElementException:" associated with an element type "NoSuchElementException" must be followed by the ' = ' character.

20:32 thoughts?

20:33 brehaut: can you create a gist or something so i can see the code?

20:33 or at least the interaction?

20:33 semperos: hmm

20:34 brehaut: im pretty certain im not following properly ;)

20:34 semperos: ok

20:34 assume I have an XML-RPC method exposed, foobar

20:34 client calls foobar

20:34 a function gets call that does nothing but (throw org.openqa.selenium.NoSuchElementException)

20:34 *gets called

20:34 missed a paren there, but you get the idea

20:35 brehaut: sure

20:35 semperos: so I pass back to the client a map

20:35 brehaut: n-e should wrap that in a fault if you dont catch it explicitly (at the level of the endpoint), which should serialize fine

20:35 semperos: that's what I thought

20:35 because I've gotten proper faults along the way

20:36 ah, furhter up the stacktrace

20:36 brehaut: ok

20:36 semperos: I have:

20:36 java.lang.IllegalArgumentException: No implementation of method: :value-type-elem of protocol: #'necessary-evil.value/ValueTypeElem found for class: clojure.lang.LazySeq

20:37 brehaut: that would be right :)

20:37 i havent provided a serialization for that because it doesnt cleanly map to the xml-rpc types

20:38 (of course, its entirely reasonable that it should have a mapping)

20:38 semperos: ok

20:38 so I'll accommodate for it on my end

20:38 brehaut: yup

20:38 semperos: should have looked further up the stack in the first place, that error I understood

20:38 brehaut: (vec my-lazy-seq) should do it

20:38 semperos: yeah

20:39 what do you think about nil?

20:39 brehaut: im working on nil

20:39 semperos: for :response-elem

20:39 I know

20:39 recommendation for the present, for dealing with nil and :response-elem? just ""?

20:39 scottj: just to make sure I'm not trying to do something that can't be done, it's possible to have a macro sh2 where (let [a "foo"] (sh2 (ls -l ~a))) => (let [a "foo"] (apply sh ("ls" "-l" a))) right?

20:40 brehaut: semperos: i think so. some sort of sentinel you arent otherwise using

20:40 semperos: k

20:40 brehaut: semperos: alternatively use a wrapper struct

20:40 semperos: ok

20:40 sorry, I think I keep asking the same questions in different guises

20:40 * semperos does that all the time on #clojure

20:40 brehaut: semperos: its no problem :)

20:41 semperos: brehaut: thanks for the help; as always, have to run now, but I appreciate your time

20:41 brehaut: semperos: later

20:41 amalloy: scottj: i don't think you can access/modify ~

20:43 scottj: amalloy: can you help me understand why not? doesn't the reader turn that into (clojure.core/unquote foo) and that's waht the macro gets?

20:43 amalloy: but if you wanted to use *a instead or something, then it would be possible

20:43 scottj: the reader actually does the unquote before giving anything to your program

20:43 &(read-string "~a")

20:43 sexpbot: ⟹ (clojure.core/unquote a)

20:43 amalloy: hm

20:44 &(let [x 1] (prn '~x))

20:44 sexpbot: ⟹ (clojure.core/unquote x) nil

20:44 amalloy: &(macroexpand '(and ~x))

20:44 sexpbot: ⟹ (clojure.core/unquote x)

20:45 devn: what's the state of the art in setting up vim with lein?

20:45 anyone have a blog post handy?

20:45 hiredman: people have been talking about writing ` as a macro, but no one has

20:46 amalloy: scottj: looks like it is possible and i'm a horrible liar. your macro will receive arguments of the form '(unquote x), which you can look for

20:46 and you have access to their lexical vars via &env

20:47 hiredman: you did, didn't you?

20:47 devn: $ alias vim emacs?

20:47 hiredman: I started once

20:47 technomancy: devn: I think there's a nailgun plugin; is that all it needs?

20:48 scottj: amalloy: maybe that's where my problem was, do I need to use &env? is there a way to do it w/o it would just be unhygeinic?

20:49 amalloy: scottj: yeah, i suppose you don't need env. just put an a in there

20:51 hiredman: amalloy: you were correct the first time

20:52 ~ is translated to unquote by the reader, and as ` is expanded it is removed

20:52 clojurebot: In Ordnung

20:52 hiredman: clojurebot: no!

20:52 clojurebot: No entiendo

20:52 amalloy: hiredman: he doesn't intend to put a ` in at all afaict

20:53 (defmacro test [form] `'~form) (test ~foo) ; yields (unquote foo)

20:53 but yes, it is liable to break if he tries to write a macro around this?

20:54 hiredman: yes

20:54 actually even if ` was rewritten as a macro that would not help in this case

20:55 amalloy: right

20:55 i think *a is clearer. a lot like the G! symbols in CL's with-gensyms

20:55 scottj: I was thinking $a as an alternative since that's shellish

20:56 but ~ has the advantage that it can apply to lists as well as symbols

20:56 amalloy: sure, whatever makes you happy. i just grabbed an unusual symbol; coincidentally it looked like C's deref operator

20:56 scottj: urgh what

20:56 hiredman: scottj: thats ~@, which is not the same

20:57 unquote-splicing

20:57 scottj: (sh (ls ~(+ 2 3))) vs (sh (ls ($ (+ 2 3))))

20:57 no, not splicing

20:57 hiredman: oh, right

20:58 scottj: so you guys are saying I can do it, but if I ever have a macro bar where (bar (sh ...~..)) then it will break?

20:59 amalloy: scottj: but wait, so what? when do you need ~(+ 2 3)? plain old (+ 2 3) will work fine

20:59 scottj: amalloy: this is for shell commands, so (sh (+ 2 3)) runs the command "+ 2 3"

20:59 hiredman: amalloy: no you'd need (let [x (+ 1 2)] (.. $x))

21:00 amalloy: hiredman: no; it's fine if his sh2 macro expands into (sh "ls" (+ 1 2))

21:01 i guess i didn't understand the intent of your sh2 thing

21:01 hiredman: mmmm

21:02 scottj: I didn't think about how sublists would work by default, if they were always escaped then you'd be right

21:02 amalloy: scottj: that seems to be overloading the ~ operator a lot. now in addition to macro-unquote, it's "when in a shell macro: if applied to a symbol then use that symbol's value; if applied to a list, parse that list as a subshell"?

21:03 scottj: no, all ~ would mean is this is clojure code

21:05 hiredman: given (sh2 (ls -l a)) you can check to see if ls and -l are locals or globals and if not str them

21:05 amalloy: scottj: perhaps use ' instead of ~? that doesn't have the nested-macro issue, and makes roughly as much sense: "don't send this to the shell for interpretation; quote it as clojure code"

21:05 scottj: good idea

21:10 amalloy: (and i can't think of any reason you'd want ' in a sh2 call)

22:20 semperos: brehaut: I've extended the ResponseElements and ValueTypeElem protocols to handle all my values

22:20 but I'm still getting the following error when that org.openqa.selenium.NoSuchElementException is thrown

22:20 brehaut: semperos: ok

22:20 semperos: https://gist.github.com/914786

22:20 brehaut: is it being wrapped in a fault?

22:21 semperos: nope

22:22 brehaut: that looks quite dire

22:22 can you interpose something to make the request yourself and catch the response?

22:24 semperos: hmm

22:24 I can make the request using ne's call method...

22:25 brehaut: you need to get the http request though

22:25 in the textual form

22:25 you can probably do it by mocking the request up using telnet

22:26 semperos: ok

22:26 brehaut: (if you dont have an http proxy tool inspector handy)

22:26 semperos: working on my work Windows machine

22:26 nothing is handy :)

22:26 brehaut: cmd + telnet is ;)

22:27 semperos: I'll fiddle and bug you in a few

22:27 thanks

22:27 brehaut: you can use the necessary-evil internal API to just generate the xml for you too

22:27 so that you dont have to type the body of your request into telnet by hand

22:28 semperos: makes sense

22:29 turns out windows 7 disables telnet by default, reenabling...

22:29 brehaut: it disables the telnet client?!

22:29 semperos: yep

22:29 professional edition, anyway

22:29 brehaut: thats messed up

22:29 semperos: :)

22:29 no biggy

22:29 top google result: http://www.fettesps.com/windows-7-enable-telnet/

22:30 pdk``: honestly i think the last time i used telnet

22:30 was just for the star wars in telnet thing

22:30 brehaut: pdk: an excellent use

22:32 semperos: what i expect to be the issue is that (catch Exception e (fault -10 (str "Exception: " e))) that is getting something out of e that when turned into a string is invalid XML

22:32 semperos: right

22:32 my thoughts as well

22:32 brehaut: if you look at https://github.com/brehaut/necessary-evil/blob/master/src/necessary_evil/xml_utils.clj#L35-58 it doesnt appear to escape anything

22:32 semperos: nope

22:33 yeah, I was trying to filter out things on my end

22:38 scottj: is there a foo where (foo bar) returns #(bar %&)?

22:42 amalloy: scottj: i can't think of a trivial one, but (comp bar list) does

22:42 cemerick: (partial apply bar)

22:43 amalloy: cemerick: going the opposite direction there

22:43 cemerick: oh, right-o

22:45 scottj: ideas for a name? vargs?

22:45 brehaut: arguments

22:45 cemerick: The name would be longer than the code… :-)

23:00 scottj: I suck so much at macros, I tried spliting sh2 into a fn that gives the right code when passed a quoted expression and then a macro that just does the quoting and calls the function but I can't get it working, http://jaderholm.com/paste/sh2.html if anyone cares

23:01 I realize sh3 is nonsense, but not sure what it should be

23:02 amalloy: scottj: (defmacro sh3 [expr] (sh2 expr))?

23:03 if all you want to do is make an auto-quoting version of s2, that's it

23:04 that said, don't use 'sh or i will come to your house and strangle you. that won't work unless the caller of the macro has (use)'d clojure.java.shell. `sh is there for you

23:05 (same for 'str)

23:07 oh. and don't use list? in macros. use seq? - a lot of code is seqs

23:07 scottj: ok, (macroexpand-1 '(sh3 (ls -l ~a))) ; => (clojure.java.shell/sh "ls" "-l" (clojure.core/str a))

23:07 (sh3 (ls -l ~a)) ; => {:exit 2, :out "", :err "/bin/ls: cannot access (clojure.core/unquote a): No such file or directory\n"}

23:07 amalloy: it turns out that makes the difference for me. with list? it fails, with seq? it works

23:08 or at any rate causes the macro version to expand to the same thing as the function version returns

23:08 scottj: oh sweet I think seq? did it

23:08 amalloy: using list? in a macro should be a compiler error :P

23:09 semperos: brehaut: I think it's probably the #<> that Clojure wraps java objects in

23:09 it's being output as a string

23:10 formatting code now to put in a gist

23:10 brehaut: semperos: ah of course. i dont know how i didnt catch this in the past

23:11 semperos: im going to write some blog content and then try to patch the xml emitter

23:11 amalloy: scottj: i do something similar in clojail: https://github.com/cognitivedissonance/clojail/blob/master/src/clojail/core.clj#L70

23:11 semperos: no worries

23:11 I had something similar happen earlier on, I forget where

23:11 brehaut: semperos: im between projects for a few hours so i'll try ot get it done ;)

23:11 semperos: so I ended up stopping using #<> in my own repl representations of objects

23:11 no worries

23:11 I'll work around it

23:11 thanks again for everything

23:13 brehaut: no worries

23:13 semperos: brehaut: here's the XML, just fyi

23:13 https://gist.github.com/914786

23:13 I just hacked your handle-post method to spit to files :)

23:13 brehaut: cheers :)

23:18 scottj: amalloy: thanks

23:33 joshua__: Awesome. Just got a 24/25 on my Programming mid term. Than the teacher decided that one of the questions was worded ambiguously and that a+b answers would both get points. Now I have 25/25.

23:36 pdk``: what material is it teaching

Logging service provided by n01se.net