#clojure log - Mar 27 2011

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

0:04 dudly: I have a few sentences:

0:04 "1. bla blah bley:"

0:04 "yes"

0:04 "2. ble blue blah"

0:05 "no"

0:05 "3. bliggidy blue blah"

0:05 "yea"

0:05 "4. hi"

0:06 "another line"

0:06 "and another"

0:06 "5. almost there"

0:06 "last line"

0:06 and I want to have them group such that

0:07 ("1. bla blah bley:" "yes") ("2. ble blah bley:") etc... ("4. hi" "another line" "and another") etc

0:09 so the distinguishing characteristic is that each grouping starts with a sentence that begins with a number

0:13 tomoj: may I ask why people are submitting these as text files?

0:14 dudly: so i need a function that iterates across the whole collection, starting the creation of a new collection every time a line starts with a number and adding each line to that new collection etc.

0:14 tomoj: cause it's a large organization

0:15 they are submitted as word files, a template that people fill out when they submit a package

0:15 tomoj: so, why word files?

0:15 is that not going to change?

0:16 dudly: I'm extracting the text out of the word files into text

0:16 tomoj: I mean, you're stuck with word files no matter how stupid they are?

0:16 dudly: no, I can't go changing the whole process

0:16 tomoj: been a while since I had to deal with that kind of shit :)

0:17 dudly: I can only really improve the workflow after the package get's to our group

0:17 tomoj: what, bureaucratic bullshit? :)

0:18 tomoj: indeed

0:19 small team means you can just say "no, this shouldn't be a word template, it should be a webpage"

0:19 dudly: yea, I'd love to change it into a webform

0:20 tomoj: trying to think of a good way to solve your problem.. it seems some kind of reduce with split-with would work, but it also seems like there's gotta be a better way

0:24 anyway, are you sure there won't be a number at the beginning of some of the lines within a group?

0:24 (besides the first of course)

0:24 dudly: well, there's brute force.. Ideally, the questions won't change very often. there are 34 questions. there are only about 6 or 7 questions that I'm pulling out of the form that are multi-line like that. So, I could just make a function for each one: filter (not "offending sentence" "next sentence" etc) (assoc "whole grouping" collection)

0:26 it's basically a result of the fact that the extraction tool is making multiple lines out of lines in a table-cell, embedded in a word document

0:26 the question is is in a table cell, the answer "yes" or "no" is in the next cell

0:26 tomoj: oh, the only user input is yes/no?

0:26 dudly: the text extracted results in lines delineated by newlines and \tabs

0:27 right

0:28 tomoj: the first line always starts with a number?

0:29 dudly: I've got it mostly ironed out, just need to concatenate those lines that are all one question

0:29 yea, and every question's first sentence always starts with a number

0:31 I already have it boiled down to a relatively structured data-structure now.. unless someone screws up the doc before they submit it, question 17 should always be, for instance, the 21st item in my datastructure, for instance

0:32 so I could just drop 21 22 and 23, and then assoc the whole concatenated string.. but that's just so ugly, and if the template changes, I'll have to much around so much in the program again.

0:33 tomoj: assoc the string?

0:33 dudly: yea, the 'correct' version of the question, rather than the broken up version

0:33 the problem is that some of the questions are like:

0:34 "16. this line"

0:34 "then this line"

0:34 instead of "16. this line then this line"

0:35 I want a "question" "answer" "question" "answer" datastructure

0:36 tomoj: this was the approach I had in mind https://gist.github.com/8c7bdf1c62f5280470e7

0:36 like I said I think there must be a better way

0:37 still dunno what you mean by "assoc the string"

0:37 assoc is something you do to maps or vectors or associative things

0:41 * dudly studies the code

0:42 tomoj: don't study it too hard, it sucks

0:43 dudly: yea, I mean, I could probably convert it to a vector and assoc the whole question back at the right index

0:44 but that would be really ugly

0:44 very brittle

0:44 tomoj: won't you still have the other lines from the question hanging there after that index?

0:44 dudly: I'd drop all the offending lines

0:44 I know their indexes because they generally wont change

0:45 *generally*.. if they do, I'd have to go back into the program and update it

0:52 I'm going to try to use what you gave me and see if that works.

1:04 no_mind: is there a library/package that will generate html form elements ?

1:05 generate and manipulate

1:09 dudly: tomoj: that worked.. worked real good

1:12 brehaut: dudly: and i had just about finished my rough hack :)

1:13 dudly: brehaut: I'm still taking entries :) seriously, I'd love to see it, as the education is the most valuable thing here

1:13 brehaut: im not sure you do. this is a huge blob of stream of conciousness coding

1:16 dudly: it's a tough one. It seems to skirt most of the use-cases that have already been solved with simple usages of partition or group-by

1:16 brehaut: dudly: https://gist.github.com/gists/888932

1:17 tomoj's solution is much cleaner

1:18 (it has names for things!)

1:19 anyway i have to disappear again

1:21 dudly: i keep getting a 500 error on that gist

1:22 keep refreshing but nothing

1:23 tomoj: me too

1:24 no_mind: didn't you ask an enlive question earlier?

1:25 brehaut: huh weird. try https://gist.github.com/888932

1:28 tomoj: perhaps there's a sense in which enlive can only manipulate and not generate

1:29 quotemstr: What would you guys recommend for a functional n-ary tree with insertion at arbitrary points and an arbitrary set of key-value pairs on each node?

1:33 brehaut: quotemstr: zippers

1:33 quotemstr: but i dont know how sorry :/

1:36 quotemstr: Heh --- that's where I ended up too. The problem is that zippers end up being very complicated as the type structure increases in complexity. But meh -- it was worth a shot.

1:36 I'll have to go with my hack and see where it ends up performance-wise.

1:38 no_mind: tomoj, I need a proper forms library that can generate and populate form elements

1:39 enlive cant do this... specially the population part

1:39 dudly: brehaut: thanks for the gist. I'm experimenting with it now.

1:41 no_mind: Looks like this JUST hit the wire: http://joost.zeekat.nl/2011/03/26/announcement-flutter-clojure-hiccup-form-fields/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+clojure+%28Planet+Clojure%29

1:42 no_mind: aha

1:43 skelternet: Anyone know of an updated version of Stu's laziness blog entry done after lazy-cons was replaced w/ lazy-seq?

1:43 dudly: serendipity

1:49 no_mind: the place where I am getting stuck in enlive is dynamically selecting form element and iterating over elements. I can generate the elements but I am not been able to figure out how to set all attributes for an element when the attributes are available as hashmap

1:49 map*

2:16 ossareh: ,(+ nil nil)

2:16 clojurebot: java.lang.NullPointerException

2:21 skelternet: anyone know of any clojure work to use the cl and the compute power on graphics cards?

2:25 tomoj: no_mind: what do you mean by population?

2:25 oh, missed your elaboration

2:26 quotemstr: how does having arbitrary kv pairs on nodes complicate things?

2:26 the nodes will just be maps

2:27 oh

2:27 nevermind :)

2:27 just have to write a custom zipper that separates your kv pairs and children data, though?

2:29 quotemstr: tomoj: Yeah.

2:29 Nothing intractable --- just tedious.

2:29 My hackish idea is to skip the zipper entirely and represent the tree-in-waiting as a flat stack of tree mutation operations.

2:30 Then when we needed the tree representations we'd just "execute" all these operations and build the real tree.

2:33 tomoj: no_mind: huh.. (apply set-attr (flatten (seq the-attr-hashmap))) seems like it would work, but..

2:40 quotemstr: isn't the problem how to execute them?

2:43 quotemstr: tomoj: Brute force suffices.

2:44 So, essentially, we don't incrementally build a tree. We maintain a list of instructions for building a tree.

2:45 tomoj: I guess in your problem you don't need to look around at what you've already done to do more?

2:45 quotemstr: You can execute those instructions using regular old imperative code.

2:45 (But the overall data structure is still functional.)

2:46 That way, the tree itself doesn't need to be persistent.

2:46 Otherwise, you're right: we've just added a turtle to the stack.

2:50 tomoj: too bad seqs aren't stacks

2:51 (repeat :turtle)

4:18 fliebel: In an if, why doesn't the else allow multiple forms? Sometimes when I have 2 branches, there is one one-liner and some work to do.

4:29 tomoj: it would be unpleasntly asymmetric

4:30 some word to _do_

4:32 I mean, what if the one-liner is on the false side?

4:32 fliebel: tomoj: not-if?

4:32 or if-not, can;t emember

4:32 tomoj: doesn't exist

4:33 ok

4:33 (if false 1 2 3 4 5) just seems weird

4:34 can't think of any really good reasons not to allow it, but, won't the code be clearer with an explicit do, anyway?

4:34 fliebel: yea, maybe...

4:43 tomoj: ah, not-if resolves the actual problems of usage

4:43 but the ambiguity is the same

4:44 er, if-not..

4:44 fliebel: tomoj: You'd expect it to work a bit more like case in that.. case.

4:44 tomoj: I don't see how case applies

4:45 fliebel: tomoj: Well, an if statement with seemingly more than 2 brances feels a lot like case.

4:45 tomoj: not at all to me

4:45 the ambiguity: do (if true 1 2 3 4 5) and (if-not false 1 2 3 4 5) return 1 or 4?

4:46 arbitrary asymmetry no matter what

4:47 fliebel: tomoj: Well, rest args can only come last, but asymmetry still.

4:47 tomoj: heh, right

4:47 that asymmetry is built in

4:54 I feel like I remember some functions/macros that break that

4:54 but can't remember which they are

4:54 ah, aset

5:21 fliebel: tomoj: Break what?

5:39 tomoj: fliebel: the rest args assymetry

5:39 fliebel: how does aset break that?

5:39 tomoj: in one sense it of course can't

5:39 fliebel: &(doc aset)

5:39 sexpbot: ⟹ "([array idx val] [array idx idx2 & idxv]); Sets the value at the index/indices. Works on Java arrays of reference types. Returns val."

5:39 tomoj: but semantically, the last arg is special

5:40 fliebel: hm, indeed.

5:40 tomoj: case breaks it too, eh? :)

5:41 fliebel: &(doc case)

5:41 sexpbot: ⟹ "Macro ([e & clauses]); Takes an expression, and a set of clauses. Each clause can take the form of either: test-constant result-expr (test-constant1 ... test-constantN) result-expr The test-constants are not evaluated. They must be compile-time literals, and need no... http://gist.github.com/889086

5:42 tomoj: " by peer [03:52]

5:42 *** waxrose (~waxrose@cpe-24-162-115-160.hot.res.rr.com) has quit: Quit:

5:42 Leaving [03:55]

5:42 *** thorwil (~thorwil@p4FFB7D94.dip.t-dialin.net) has joined channel #clojure

5:42 [03:56]

5:42 *** xkb (~svdberg@svdb.xs4all.nl) has joined channel #clojure [03:58]

5:42 *** OlegYch|h (~OlegYch@ has joined channel #clojure [03:59]

5:43 thorwil: ?

5:43 tomoj: did I avoid paste spam?

5:43 fliebel: tomoj: What was that? did you pipe the output of your irc client back in?

5:43 tomoj: shoot

5:43 how much got through? (what was the last thing I said before I said "did I avoid paste spam?"

5:44 fliebel: ~10 lines

5:44 clojurebot: I don't understand.

5:44 fliebel: less

5:44 You said something about case

5:44 tomoj: ok, good, had almost 100 pasted in

5:45 fliebel: tomoj: Good ctrl-C'ing :)

5:45 tomoj: problem is that kill-yank preserves text color, so if I accidentally kill+yank a bunch of backlog, it looks just like an input prompt

5:46 so I somehow got some backlog pasted in, then what I really wanted to say, but couldn't tell until sending

5:46 fliebel: tomoj: With great power comes great responsibility ;P

5:46 tomoj: what I really wanted to say was "A single default expression can follow the clauses, and its value will be returned if no clause matches."

5:47 fliebel: wait.. so when I do :else it's just because that symbol is truthy? So I could juts as well say :foo or nothing at all...

5:48 tomoj: for cond, yes

5:48 for case, :else is superfluous

5:48 fliebel: oh, wait, case

5:49 tomoj: er.. not superfluous, probably just wrong,eh?

5:49 fliebel: yea

5:49 tomoj: ..fuck it's 5am..

5:49 fliebel: It's not...

5:50 Huh!? NullPointerException [trace missing]

5:51 tomoj: haha

5:51 fliebel: Where did the trace go?

5:51 tomoj: don't think I've seen that before

5:52 fliebel: It does that consistently, maybe something with lazy stuff and closures?

5:55 I got it down to 4 lines, I think.

6:02 Okay, problem solved, but still no idea where my stack trace went.

6:45 thorwil: in Enlive's source, i see some "defn- ". i see no definition for those and google refuses to deliver an hits that are not actuall about plain defn. anyone here knows more about that?

6:45 fliebel: thorwil: defn- defines a private function

6:46 thorwil: But you can also say (defn ^:private) I think, so I heard it's considered a legacy feature.

6:47 angerman: why do I want private fns in the first place?

6:48 fliebel: angerman: Since people are not supposed to depend on them , you can change them at will without breaking your api.

6:49 angerman: what happens if you made some oversight and by privatizing that fn you made it extraordinary cumbersome to work with your library?

6:49 I'd prefere to use a "private" namespace.

6:50 fliebel: angerman: Then you have a bad design. Luckily, you can still access those fns, like in Python, so it's not like thei're lost forever.

6:51 (you being the writer, not the user of course)

6:51 ( in most cases at least)

6:52 angerman: that's been the experience from the point of a library user.

6:53 fliebel: angerman: What is a private ns? I'd rather group my functions by function, rather than by access.

6:53 angerman: fliebel: *ns*.private/

9:31 krl: hmm. i still get by lein swank -> java.net.BindException: Cannot assign requested address (NO_SOURCE_FILE:1)

9:32 hmm

9:48 raek: krl: sounds like you have an old swank server running somewhere

9:48 krl: i have done killall java

9:48 pretty sure this is not the case

9:48 also, different ports give the same error

9:49 p_l|home: raek: or the socket wasn't closed and haven't been recycled yet

9:50 krl: and the NO_SOURCE_FILE thing is just noise?

9:51 p_l|home: NO_SOURCE_FILE sounds to me like a case of error being raised from code that wasn't loaded from known source file

9:51 that is, the VM can't deduce source file for the code raising the error

9:58 krl: p_l|home: yeah makes sense

9:59 i'll just reboot to hard-exclude any lingering socket problems. brb

9:59 p_l|home: krl: remember to set up socket reuse

10:00 (a sysctl on linux, dunno about other systems)

10:01 fliebel: Is there any difference between nanoTime and currentTimeMillis besides the nano/milli? My computer wont do exactly nano, so it seems milli is good enough, but are there any other reasons to use one or the other?

10:03 krl: p_l|home: reboot actually seems to have solved it. i'll look up socket reuse, thanks!

10:04 fliebel: (wyf is 20N?)

10:04 Caffeine: fliebel: I don't know who would use nano and why... I've been told a couple of times that the JVM wasn't precise enough anyway. I always use milli.

10:04 fliebel: ah clojure.lang.BigInt

10:10 p_l|home: krl: because reboot clears the state

10:18 Licenser: has anyone played with jain-sip and clojure?

10:41 fliebel: It seems there is now way I can make future-call use my own threadpool? I don't feel like running 2 threadpools.

11:00 krzysz00: Does clojure have something similar to Java's import?

11:01 angerman: krzysz00: (import …) ; (require … ) ; (user … ) ?

11:10 krzysz00: What's the #^ reader macro do. Google's not helping, sadly?

11:11 angerman: krzysz00: meta data

11:12 sritchie: krzysz00: it's been replaced by ^

11:12 angerman: ,(meta #^ :private 'foo)

11:12 clojurebot: nil

11:13 angerman: ,(meta ^:private 'foo)

11:13 clojurebot: nil

11:13 angerman: ?:-|

11:13 sritchie: ,(def ^{:doc "The number 5."} testnumber 5)

11:13 clojurebot: DENIED

11:14 sritchie: haha, bummer

11:14 jonh: hehe

11:14 angerman: ,(let [x ^{:doc "yes!"} 5] (doc x))

11:14 clojurebot: Metadata can only be applied to IMetas

11:14 angerman: ,(let [x ^{:doc "yes!"} (fn [_] "no!")] (doc x))

11:14 clojurebot: Huh?

11:14 Raynes: Might as well give that up.

11:15 angerman: now that response caught me by suprise

11:17 ,(let [x ^{:doc "yes!"} (fn [_] "no!")] (meta x))

11:17 clojurebot: {:doc "yes!"}

11:17 angerman: hm. no :line?

11:22 fliebel: How do I iterate over a LinkedBlockingQueue in a blocking manner? It just gives me all it can and quits. I guess I need to .take in a loop manually then?

11:28 * Raynes looks at his code to see how he did that.

11:28 fliebel: (while true (.take)) is what I have now.

11:29 Raynes: fliebel: That's basically what I have, except I'm checking if the queue is empty.

11:29 krzysz00: What do you need to do to declare a var final (I'm trying to translate some Java code)?

11:29 angerman: krzysz00: why final?

11:30 krzysz00: does it need to be final? If so, why?

11:30 Raynes: Declaring a var final doesn't make a whole lot of sense. You don't have to translate Java directly.

11:32 krzysz00: good point

11:34 fliebel: Hm, I've needed a combination of assoc and assoc-in a few times now. Does it exist? I want to change multiple keys in a nested structure at once.

11:35 krzysz00: In Common Lisp I would write (let ((button (new button args*))) (frob button)) Does clojure still use let for that, or binding, or something else?

11:36 angerman: (let [button (button. args*)] (frob button))

11:37 assuming button is a Java class.

11:37 danlarkin: or better yet just (frob (Button. args))

11:37 angerman: otherwise use what ever constructor you have.

11:40 :/

11:41 iOS devel seems to converge towards just paying the apple fee.

11:41 (for me that is)

11:54 krzysz00: how would I rewrite this bit of Java into clojurehttp://pastebin.com/Qdht4CN3

11:55 er .whoops http://pastebin.com/Qdht4CN3

11:58 TimMc: Depends on what R is.

11:58 Is that a class?

11:59 p_l|home: TimMc: R is an autogenerated read-only class full of static members

12:00 krzysz00: I got the R bit as (let [button. (.findViewById R$id/quit_button)]

12:01 TimMc: Why the period at the end of button ?

12:02 angerman: ,(let [x. (fn [] "x")] (x.))

12:02 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: x

12:02 angerman: ,(let [x. (fn [] "x")] x.)

12:02 clojurebot: java.lang.ClassFormatError: Illegal field name "x." in class sandbox$eval5877

12:03 krzysz00: typo

12:03 TimMc: So, inside the let, you can do (.setOnClickListener button (proxy [View$OnClickListener] [] (onClick [^View v] ...))) or something.

12:03 I may have gotten the proxy syntax slightly wrong.

12:04 krzysz00: oh. proxy, right. I'll look that up

12:05 fliebel: The repl is biting me! How can I reload/use a lib without getting errors because I have a function named future?

12:05 TimMc: krzysz00: In general, http://clojure.org/java_interop has what you need for using Java libs from Clojure.

12:05 fliebel: refer-clojure doesn't seem to help.

12:06 TimMc: fliebel: (:use [foo.bar :exclude [future]])

12:07 or :rename

13:17 fliebel: Still not working: WARNING: future already refers to: #'clojure.core/future in namespace: ant-mine.animate, being replaced by: #'ant-mine.schedule/future ns line in animate reads (:refer-clojure :exlude [future])

13:18 aua: begginer Clojurer here

13:18 trying to implement markov chain algorithm

13:19 and seeing low performance

13:19 fliebel: aua: Hold on! *browsing gists*

13:19 aua: not looking for a great implementation ;-)

13:19 just trying to improve my clojure-fu

13:20 especially knowing about performance

13:20 fliebel: aua: Oh, okay, anyway, this is mine, doing rock paper scisors.

13:20 https://gist.github.com/564552

13:22 aua: @fliebel Thx! seems a nice solution

13:22 will try to upload mine somewhere

13:22 and please could you tell me some tips?

13:23 fliebel: sure

13:24 aua: https://gist.github.com/889388

13:24 just interested in creating the Markov map

13:24 i.e. markov-hash function

13:25 still trying to wrap my head about functional concepts

13:25 :-)

13:26 "markov-hash function" -> "markov function"

13:27 fliebel: you can replace (fn [v1 v2] (concat v1 v2) with just concat

13:28 aua: How about the solution itself?

13:29 maybe I'm creating to much map and then mergeing them...

13:29 ...seems inneficient

13:29 fliebel: aua: Looks okay to me, but I haven't read it very well. I'm trying to solve some problems myself as well.

13:31 aua: @fliebel np, thanks for your help!

13:31 ataggart: the body of markov looks like it could be done with reduce instead of (apply merge-with...)

13:33 aua: tried a reduce solution but performed almost the same :(

13:33 let me paste it

13:34 version with reduce https://gist.github.com/889395

13:39 comparing with a Python version I made

13:39 Python: 1sec, Clojure 6sec

13:42 schlechtv: What's the most idiomatic way to build a seq of differences between the elements of another seq, i.e. [4 5 5 6] -> [1 0 1]?

13:47 avysk: What about (defn f [lst] (map - lst (rest lst)))

13:47 ?

13:47 ataggart: ^

13:48 schlechtv: avysk: imagine me slapping my forehead repeatedly for not thinking of it myself

13:48 avysk: Thanks!

13:49 avysk: welcome :)

13:49 TimMc: ,(map (partial apply -) (partition 2 1 [4 5 5 6]))

13:49 clojurebot: (-1 0 -1)

13:50 TimMc: (Less readable, but more fun.)

13:51 avysk: That creates a load for garbage collector later, no?

13:51 ataggart: yup

14:09 fliebel: refer-clojure is not working! (i'm doing something wrong, but it's driving me mad!)

14:11 raek: (remove-ns 'foo) (ns foo (:refer-clojure :exclude [var1 var2])) ?

14:11 fliebel: I have a ns that defines future, and this is my ns declaration: (ns ant-mine.animate (:refer-clojure :exlude [future]) (:use [ant-mine [schedule :only [future]] [core :only [state]]])), causing WARNING: future already refers to: #'clojure.core/future in namespace: ant-mine.animate, being replaced by: #'ant-mine.schedule/future

14:11 raek: remove-ns? nice...

14:12 raek: fliebel: :exclude, not :exlude

14:12 fliebel: raek: Whoa! dud, why dodn;t clojure complain about that?

14:12 thanks

14:12 raek: I tend to misspell that one too

14:13 fliebel: *phew*

14:13 raek: fliebel: if you call remove-ns, make sure you remove all ns that used it too, otherwise you will get a lot of errors

14:14 fliebel: raek: Now that I can reload, I don;t care about remove-ns :)

14:14 * fliebel needs to swap his ' and ; keys

14:19 LauJensen: Are there any simple cryptography libs out there yet?

14:22 ataggart: LauJensen: what kind do you need?

14:23 LauJensen: (encrypt "pass" "foo") = "%¤%", (decrypt...), basically

14:24 ataggart: symmetric/asymmetric? for external consumption or internal?

14:24 raek: LauJensen: for password hashing and verification, I recommend http://www.mindrot.org/projects/jBCrypt/

14:24 LauJensen: raek: Thanks - Clojure wrapped yet?

14:24 TimMc: LauJensen: There's no such thing as "generic encryption".

14:24 LauJensen: TimMc: You obviously haven't seen my user.clj :)

14:24 TimMc: ?

14:25 LauJensen: It was a joke, suggesting that I had handcrafted a generic encryption algorithm

14:25 TimMc: Ah, I thought you were referring to obfuscated code. :-)

14:25 LauJensen: Naah, thats the good thing about Clojure, you dont need to obfuscate anything :)

14:26 TimMc: Some people seem to have that need.

14:26 raek: LauJensen: (defn bcrypt-hashpw [password salt] (BCrypt/hashpw password salt)) there, I made you one :)

14:26 * TimMc stares pointedly at the point-free crowd

14:26 LauJensen: TimMc: It was a joke, suggesting that Clojure code is write-only

14:26 p_l|home: LauJensen: nope, Clojure is perfectly readable... now, APL in EBCDIC... :P

14:26 LauJensen: ah :)

14:26 raek: you only need to call three static methods

14:26 LauJensen: raek: You're the man :)

14:26 ataggart: keyczar would be good if you want a high-level api and don't need external parties consuming the encrypted content

14:28 LauJensen: ataggart: I dont, but what raek suggested seems to fit the bill

14:28 And since this is just a trivial financial system trading millions upon millions on the stockmarketing every minute, we dont need to get anal about security

14:29 ataggart: ah, so you just need a password hashing scheme? Then bcrypt is what I would go with too, though I would be concerned about a new implementation of it. Crypto is easy to get wrong.

14:31 LauJensen: p_l|home: Actually APL is a walk in the park once you're comfy with J

14:32 ataggart: hmm, I'm looking at the javadoc for the bcrypt... does anyone find it odd that the number of rounds is only configurable on the salt generation and not the hashpw generation?

14:34 LauJensen: why?

14:34 clojurebot: why not?

14:36 p_l|home: LauJensen: APL/360 with original codepage... viewed on ANSI terminal

14:37 ataggart: the number of rounds increases the cost of the verification process., which is what you want when you're guarding against someone trying to build a rainbow table

14:38 http://codahale.com/how-to-safely-store-a-password/

14:40 nickik: Hi, im working with enlive for the first time. I wrote this html snippet and I want to fill it up with some example content. http://paste.lisp.org/display/120938. Here is what I tried http://paste.lisp.org/display/120939. Can somebody help?

14:42 LauJensen: nickik: :.blogpost is class="blogpost", your article is #blogpost.

14:42 I think you want [:#blogpost :> any-node] actually

14:42 ataggart: LauJensen: And there's a good case to be made that crypto primitives should never be implemented in a managed environment. Being able to control the time profile is critical to avoiding timing attacks, and with JIT, GC, etc. that's not possible with java.

14:43 LauJensen: Right

14:44 fliebel: *blink* Did I just kill Swing?

14:46 ataggart: fliebel: many a freshman CS major would thank you if you did.

14:47 fliebel: ataggart: The best I can do is making it throw exceptions, I'm afraid.

14:47 nickik: LauJensen, good to know that :. means class. Why do I need that any-node? It works know but the <article>-tag is displayed. How can I fix this?

14:47 *now

14:48 LauJensen: nickik: :> any-node, means match everything directly under article, but not article

14:48 ie. article wont appear after the transformation

14:48 nickik: but it should

14:49 I mean the mark up would be wrong otherwise.

14:49 LauJensen: Then wrap the whole thing in a <body> and pass [:body :> any-node]

14:50 nickik: What wrong with just matching :#blogpost?

14:51 LauJensen: Read the above

14:52 nickik: Yeah sure that works to but why is one better then the other? It seams to me that wraping the article with some body-tag will obscure my template.

14:52 *too

14:54 fliebel: Interesting trick: How many times does the print statements run? http://pastebin.com/JLxeAKSt

15:01 raek: fliebel: once?

15:02 ,(macroexpand-1 '(future (process) (Thread/yield) (recur)))

15:02 clojurebot: (clojure.core/future-call (fn* [] (process) (Thread/yield) (recur)))

15:02 opqdonut: yeah it recurs to the future-called fn

15:05 fliebel: right :)

15:06 anonymou1e89: is there something special to know about calling functions from within deftype?

15:07 I have a problem with number of arguments

15:07 raek: anonymou1e89: not with calling. but note that protocols can't have "& more" params

15:09 anonymou1e89: also, how do I call functions of the type from within the type?

15:10 raek: anonymou1e89: you mean something like this? (deftype Foo [...] Protocol1 (method1 [this] ...) (method2 [this] (method1 this)))

15:11 i.e. you do as you usually do when you call a protocol method

15:13 anonymou1e89: raek: ok, sorry for the silly question. that makes perfect sense

15:14 actually one more question. Can types and records have private fields and functions?

15:15 fliebel: (does anyone know a little free app to record a screen in mac, or how to save a java graphic to a file?)

15:16 raek: they can't have private methods (just use usual defn- for that). I'm not sure if deftype's fields are public or private

15:17 the things you put in defrecord/deftype are only the things that implement the protocols/interfaces

15:17 anonymou1e89: raek: oh I see. actually I think they don't have accessor's

15:17 raek: ,(deftype Foo [x])

15:17 clojurebot: sandbox.Foo

15:17 raek: ,(.x (Foo. 1))

15:18 clojurebot: 1

15:18 anonymou1e89: oops

15:18 :)

15:18 raek: apparently, they are public. but you still have to know the name of them

15:25 anonymou1e89: my arity problem was due to lein not recompiling types (I think). I did "lein clean" and things were as expected

16:00 TimMc: Yay, I can do proper 3D rendering now!

18:41 phenom_: anyone here experienced with nio ?

18:41 Bed_: I was wondering. Would it be possible to make your own loop function without macros?

18:41 , (defn myloop [s1 s2 func)((func func) s1 s2)

18:41 clojurebot: Unmatched delimiter: )

18:41 Bed_: , (defn myloop [s1 s2] func)((func func) s1 s2)

18:41 clojurebot: DENIED

18:42 Bed_: No, you should be DENIED.

18:42 & (defn myloop [s1 s2] func)((func func) s1 s2)

18:42 sexpbot: java.lang.SecurityException: You tripped the alarm! def is bad!

18:43 Bed_: Nah, I was just trying to construct my own loop.

18:43 brehaut: Bed_: in theory yes but in practice you are going to run into problems with tail calls

18:45 Bed_: I constructed something http://pastebin.com/8cfRt4Dz

18:45 Although it still has bugs probably

18:46 I am wondering this pure theoritically.

18:46 For now

18:46 Then I will try to find a way to get tail recursion.

18:46 brehaut: Bed_: then purely theoretically yes entirely possible. Languages like Haskell dont have any built in loop syntax, its all built on top of tailcalls

18:47 Bed_: Do you have an example of the thing I am trying to construct without macros?

18:47 brehaut: Bed_: your definition of myloop is confusing at best

18:48 Bed_: Or is there a well known name for the construct I am trying to create.

18:48 brehaut: Bed_: not in clojure

18:48 Bed_: i'd call the general concept a 'loop combinator' i guess. i dont know what your specific one is trying to do

18:49 Bed_: I am trying to mimic named lets like they appear in scheme. But I am trying to avoid using macros.

18:50 brehaut: im not familiar with named lets in scheme

18:50 Bed_: named lets are a bit like the (loop, iter)-construct in clojure but they don't have to be tail recursive

18:51 I should probably ask this question to a schemer I think.

18:51 brehaut: i think so

18:52 Bed_: I though that there would be a lot of overlap between schemers and clojurers.

18:52 brehaut: there is some overlap

18:52 i dont know if anyone has measured it though

18:55 phenom_: argh, dealing with nio in clojure is ugly

18:56 reading, rewinding, putting, getting bleh

19:04 TimMc: Bed_: You can construct recursive functions using the omega combinator.

19:06 Bed_: https://secure.wikimedia.org/wikipedia/en/wiki/Fixed_point_combinator#Example_in_Scheme

19:06 Bed_: Is the omega combinator syntactic or macroic?

19:06 TimMc: It's just a function.

19:06 brehaut: TimMc: how does omega differ from Y?

19:07 TimMc: Y is built on omega, I think.

19:08 Bed_: I am not sure if a fixed point combinator is what I was looking for.

19:08 TimMc: Don't ask me to explain how it works. I got my brain wrapped around it once upon a time, but have since forgotten.

19:08 Bed_: A fixed combinator is a solver for the equation f(x) = x if I understand correctly.

19:08 brehaut: TimMc: likewise :)

19:09 Bed_: the Y combinator allows you to implement arbitrary recursion in a language that does not natively support it

19:09 TimMc: Bed_: Did you follow the link?

19:09 I believe that Scheme code gives you (fact 4) => 24

19:09 Bed_: Yes, but I didn't read it yet.

19:10 TimMc: Don't worry about the first code block, just look at the second. THat's fact (a looping calculation) done without syntactic recursion.

19:10 Bed_: The scheme code looks like this: http://pastebin.com/uPMN9g8b

19:11 TimMc: What is it supposed to do?

19:11 brehaut: Bed_: then why havent you just ported it directly?

19:12 (defn myloop [s1 s2 f] ((f f) s1 s2))

19:12 Bed_: Since I am a bad programmer.

19:12 TimMc: haha

19:13 Convert code, become a better one! :-)

19:13 brehaut: if you want it to not explode your stack you probably want to investigate trampoline ##(doc trampoline)

19:13 sexpbot: ⟹ "([f] [f & args]); trampoline can be used to convert algorithms requiring mutual recursion without stack consumption. Calls f with supplied args, if any. If f returns a fn, calls that fn with no arguments, and continues to repeat, until the return value is not a fn, ... http://gist.github.com/889743

19:14 brehaut: which is probably going to bake your noodle trying to get working but the exercise will probably be worth it

19:14 sritchie: quick non-clojure survey (sorry!)... how do you folks on small programming teams organize notes that need to get between, say, four or five team members?

19:15 other than email. the other two folks on my team are away for a while, and I'm thinking of setting up an internal wiki they can peruse

19:15 Bed_: Those functional languages distract me from doing any practical work :P

19:16 brehaut: sritchie: wiki's can be good but it requires that at least one person is really dedicated to maintaining it, otherwise it will become a wasteland

19:16 sritchie: brehaut: that'

19:16 brehaut: that's kind of what I'm thinking will happen

19:17 TimMc: You really need group buy-in for a wiki.

19:17 sritchie: everyone in a small team builds up the same body of knowledge, roughly, branching out as they go -- tough to track the process, though

19:17 yeah, and we have to assume everyone in the team will be motivated by self interest

19:18 (> reading content-creation), unless everyone's bought in

19:18 brehaut: personally i would just ask that everyone writes good notes in a text file in the VCS filesystem

19:19 sritchie: haha, I can see this is a thorny question, maybe this isn't the forum, and we should all just take over a coffee shop and pass napkins around

19:19 brehaut: sritchie: probably. 'groupware' is a remarkably tricky problem

19:20 hurrah for 90s buzzwords

19:21 sritchie: I might like a bot that could scan for corporate lingo

19:22 brehaut: and punishes people for talking about synergy?

19:22 sritchie: it could even pose as a real user, and reply with other buzzword laced questions, goading the user on

19:22 you'd have a flubber effect, with corporate speak getting out of control

19:22 brehaut: i dont think the world needs any more trolls (automated or otherwise)

19:23 sritchie: haha, fair point

19:23 okay, I'll go type up these damned notes in a text file, and leave groupware to the 90s

19:24 brehaut: sritchie: i think text files are good because theres such a small barrier to maintaining them and no new tools needed

19:25 at least until you have a better idea of how the process is working

19:25 sritchie: brehaut: yeah, and including them in the git repo keeps them close to the code

19:25 brehaut: yup

19:26 sritchie: brehaut: I guess the idea is sort of an internal blog for the three of us, where we can pitch each other -- the "post" I'd envision would be a summary of research, and would ideally boil down into, say, items in pivotal tracker

19:26 but would provide explanation for those new things, and justify their existence

19:28 TimMc: Blog might have high barrier to entry. People might feel constrained to use complete thoughts. :-P

19:29 sritchie: we could even go to the full vlog level, with video posts, pitching features

19:30 a three person committee! every startup's dream

19:31 gfrlog: $findfn {1 3, 4 3, 32 3, 85 2, 9 2} {3 [1 4 32], 2 [85 9]}

19:31 sexpbot: []

19:31 gfrlog: dangit

19:33 TimMc: group keys by values, eh?

19:33 gfrlog: yep

19:33 brehaut: ,(into {} (map (fn [[k v]] [k (map second v)]) (group-by first (map reverse {1 3, 4 3, 32 3, 85 2, 9 2})))

19:33 clojurebot: EOF while reading

19:34 brehaut: ,(into {} (map (fn [[k v]] [k (map second v)]) (group-by first (map reverse {1 3, 4 3, 32 3, 85 2, 9 2}))))

19:34 clojurebot: {3 (1 4 32), 2 (85 9)}

19:34 TimMc: damn, brehaut, you're fast

19:34 gfrlog: brehaut: I used (group-by m (keys m))

19:34 brehaut: im sure it could be cleaner

19:34 TimMc: I was going to use merge-with or something.

19:35 brehaut: gfrlog: thats really nice

19:35 (inc gfrlog)

19:35 sexpbot: ⟹ 1

19:35 gfrlog: brehaut: thx

19:36 TimMc: damn, gfrlog, you're better :-P

19:36 gfrlog: brehaut: I actually had already wrote it that way, but it was the sort of thing I thought might be lying around in core

19:36 brehaut: thats areally inspired solution

19:36 gfrlog: TimMc: better than what?

19:37 TimMc: I was making fun of brehaut (and myself, actually.)

19:37 brehaut: TimMc: fair enough, my way looks barbaric comparatively

19:38 gfrlog: TimMc: okay. I'm lost in layers of interpretation, so I'll just throw an exception, catch it, and return "we all had a good time just then"

19:38 TimMc: Oh wait, gfrlog actually posted 3 minutes before brehaut... I thought it was more like 20 seconds for some reason.

19:39 Stupid IRC time warpage.

19:40 I'm still working through group-by.

19:40 gfrlog: TimMc: that's a fun one; brehaut used it somehow.

19:41 ,(group-by #(rem % 2) (range 10))

19:41 clojurebot: {0 [0 2 4 6 8], 1 [1 3 5 7 9]}

19:41 gfrlog: ,split

19:41 clojurebot: java.lang.Exception: Unable to resolve symbol: split in this context

19:41 gfrlog: ,clojure.string/split

19:41 clojurebot: java.lang.ClassNotFoundException: clojure.string

19:41 gfrlog: ,clojure.contrib.str-utils2/split

19:41 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.str-utils2

19:41 gfrlog: worthless

19:41 brehaut: TimMc: the big difference between mine and gfrlog's is that i manually take time to flip the map about, group it naively and then stitch it all together, rather than just using the function nature of maps

19:43 TimMc: ,(apply group-by ((juxt identity keys) {1 3, 4 3, 32 3, 85 2, 9 2}))

19:43 gfrlog: I feel like the most common cause of writing unnecessarily large expressions is forgetting that various objects are functions

19:43 clojurebot: {3 [1 4 32], 2 [85 9]}

19:43 gfrlog: TimMc: what the heck is that

19:43 TimMc: JUXT!

19:44 gfrlog: TimMc: were you just trying to figure out how to work that in?

19:44 TimMc: It's your code, only with juxt!

19:44 gfrlog: lemme see if I can get comp in there

19:44 brehaut: the padawan is learning

19:45 (comp (partial apply group-by) (juxt identity, keys))

19:45 gfrlog: speaking of nicer code, just 5 seconds ago I changed #(not= % a) to (complement #{a})

19:45 TimMc: hum

19:46 brehaut: complements of sets are great

19:46 gfrlog: yeah

19:46 * TimMc distrusts all this fanciness at some level

19:46 brehaut: i think i have ended up using them more than sets as functions

19:46 TimMc: the point free trifecta ?

19:48 TimMc: or data as functions?

19:48 TimMc: (complement #{a}) is like really dense but good prose -- I eventually get the point, and it is an admirably clever use of language... but I can't just *read* it.

19:48 Bed_: Hey, that y-combinator actually works.

19:48 TimMc: Bed_: Cool, huh?

19:48 gfrlog: TimMc: you don't think you get used to it eventually?

19:49 TimMc: gfrlog: I might, but what about future readers of my code?

19:49 There is something to be said for writing simply.

19:49 brehaut: TimMc: i think its a matter of perspective. (complement set) is the simplest way i could imagine it

19:50 gfrlog: I guess it depends on the future reader

19:50 TimMc: Jargon can convey information in a succinct and precise manner, but it is tempting to use it just because it is there.

19:50 #(not= % a) is pretty damn clear, succinct, readable, fast, and simple -- but it isn't clever.

19:51 ...and maybe cleverness ought to be sacrificed for readable code.

19:51 brehaut: perhaps in the case of a single element

19:51 Bed_: TimMc: very cool

19:52 brehaut: TimMc: what about #(and (not= % a) (not= % b)) vs (complement #{a b}) ?

19:52 gfrlog: I wonder how much of this is just damage from imperative programming

19:52 brehaut: (i assume my boolean logic is broken in the first example)

19:52 TimMc: Bed_: It's crazy stuff. Try to work through *how* it works -- you'll learn a lot. (Then you can foget it and use the damn looping constructs. :-P)

19:52 brehaut: When you start looking at multiple elements, I think the balance shifts.

19:52 gfrlog: brehaut: the bools looks goods to me

19:53 brehaut: gfrlog: thats pure luck :P

19:53 gfrlog: &split

19:53 sexpbot: java.lang.Exception: Unable to resolve symbol: split in this context

19:54 gfrlog: &clojure.string/split

19:54 sexpbot: ⟹ #<string$split clojure.string$split@1243a0f>

19:54 TimMc: My girlfriend is looking at work in science popularization, and she chides me for gratuitous use of jargon all the time. :-)

19:54 gfrlog: &(group-by count (clojure.string/split #" " "This expression will group the words by how many letters they have"))

19:54 sexpbot: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.regex.Pattern

19:54 gfrlog: &(group-by count (clojure.string/split "This expression will group the words by how many letters they have" #" "))

19:54 sexpbot: ⟹ {4 ["This" "will" "many" "they" "have"], 10 ["expression"], 5 ["group" "words"], 3 ["the" "how"], 2 ["by"], 7 ["letters"]}

19:55 Bed_: It is very complicated, but I really want to learn how it works.

19:55 gfrlog: TimMc: who pays for science popularization?

19:56 TimMc: Bed_: Start by creating a factorial function that takes an extra parameter -- a function to call with the accumulated data.

19:57 brehaut: TimMc: i dont know if i agree with that; it makes sense when the jargon is ill defined or has a blurry meaning (eg: Functional Programming, Object Oriented, Monads, Combinators etc) but when the term is very precisely defined (as you get with a function definition) it seems to be beneficial to use the jargon

19:57 TimMc: Bed_: That should give you a start on figuring it out.

19:58 Bed_: That would require me to wrap the parameters in a list or as values wouldn't it?

19:58 brehaut: TimMc: because then you have a suscinct definition and if your audience doesnt understand some parts of it its very clear for both parties where the problem lies.

19:58 TimMc: Bed_: Nope, just (define (fact n acc f) ...)

19:59 Bed_: which then calls (f ...) in the tail position.

19:59 gfrlog: Dunno, actually.

20:00 brehaut: Idioms in Clojure work the same way as jargon -- a visual stumbling block that you have to pause and process, because you have to swap in a mental model or similar.

20:00 (Idioms in any programming language, of course.)

20:01 It's not that they're *bad*, it's that they break up the flow of reading for a non-expert.

20:01 gfrlog: Most of the clojure I write is for myself

20:02 brehaut: TimMc: i think that it makes it easier for the non-expert; its clear where their understanding is missing. if you have a soup of primatives then you need to understand everything at the lower level and then hold it all in your head to build up the bigger picture

20:02 TimMc: Clearly-named functions help with that, yes.

20:03 gfrlog: like ##complement

20:03 like ##(doc complement)

20:03 sexpbot: ⟹ "([f]); Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value."

20:03 gfrlog: ah there it goes

20:03 I'm getting good at sexpbot

20:03 TimMc: If gfrlog does (def group-by-vals (comp (partial apply group-by) (juxt identity keys))) and slaps on a docstring, who cares?

20:04 Or group-keys or something.

20:05 Bed_: Okay, I constructed it.lambda (n acc)

20:05 (if (= n 0) acc

20:05 TimMc: Leaving it as (group-by m (keys m)) relies on the use of a map as a function in a place where something complicated is *already* going on.

20:05 Bed_: ((iter iter) (- n 1) (* n acc))))))

20:05 gfrlog: TimMc: why not slap on a docstring then?

20:06 TimMc: gfrlog: Sorry, I mixed examples.

20:06 Pretend that first thing was (defn group-keys [m] (group-by m (keys m)))

20:06 Inlining vs. naming in other words.

20:07 gfrlog: ah very good

20:07 I'm fine with that

20:07 I did it that way actually

20:07 cept I called it invert and neglected the doc-string :)

20:08 TimMc: invert?

20:08 keys-by-val

20:09 gfrlog: it all good

20:09 there's no bad name for that function

20:09 TimMc: "fred"

20:09 That's a bad name.

20:09 gfrlog: actually fred seems to like it

20:09 he's responding to it at least, and he's smiling more than he used to

20:09 TimMc: :-(

20:10 Didn't you see the sign on the door? "Don't tease the name-obsessors."

20:11 gfrlog: :)

20:12 Fred just went and defn-ed himself in a few other namespaces

20:13 This would be a good time for somebody to say "Functions hate being anthropomorphized"

20:14 Adamant: but they love morphisms! (if you're in #agda)

20:14 gfrlog: :)

20:15 Golly I just stared at "Caused by: java.lang.IllegalArgumentException: Parameter declaration let should be a vector" for like 5 minutes before I figured out I had written 'defn' instead of 'deftest'

20:17 Adamant: I just read 2 sentences about agda and I'm completely lost.

20:17 Adamant: gfrlog: start with #haskell

20:17 gfrlog: Adamant: yeah, it had that flavor

20:17 * Adamant is still confused by agda as well

20:18 gfrlog: Haskell needs more parentheses

20:18 brehaut: gfrlog: just use liskell then

20:19 gfrlog: $google liskell

20:19 sexpbot: First out of 158 results is: About Liskell

20:19 http://www.liskell.org/

20:19 brehaut: http://www.readwriteweb.com/hack/2010/11/haskell-with-lisp-syntax.php

20:19 oh. or that :P

20:20 gfrlog: brehaut: sexpbot's didn't work anyhow

20:21 sexpbot: BAD!

20:22 ssideris: hello, I'm writing a macro and in order to test it I'm trying to do:

20:23 (pp/pprint (macroexpand-1 '(make-listeners f)))

20:23 where f is the map that the macro expects as a parameter

20:23 because of the quote, I get "Don't know how to create ISeq from: clojure.lang.Symbol"

20:24 the macro works as expected when I replace f with a literal map

20:24 any way around this?

20:24 clojurebot: Gabh mo leithscéal?

20:25 brehaut: ,(let [f 1] (macroexpand-1 `(inc ,f)))

20:25 clojurebot: (clojure.core/inc sandbox/f)

20:26 TimMc: ssideris: You should be using ` instead of ' in general anyway.

20:26 (syntax-quote vs. quote)

20:26 brehaut: ssideris: alternatively if you want to have the value of f in the form rahter than the symbol, you can do ##(let [f 1] (macroexpand-1 `(inc ~f)))

20:26 sexpbot: ⟹ (clojure.core/inc 1)

20:27 TimMc: brehaut: Did you forget that comma is whitespace?

20:27 I do that all the time.

20:28 brehaut: TimMc: a) yes, and b) i may have confused things with older lisps

20:28 ssideris: with this I still get an error (macroexpand-1 `(make-listeners ~f))

20:29 but a different one...

20:29 Don't know how to create ISeq from: clarity.core$f

20:29 clarity.core is my namespace

20:29 TimMc: ssideris: What is f, then?

20:30 ssideris: oh crap, I had defined f with defn rather than def

20:30 (it's a map)

20:30 sorry!

20:30 it works now, thanks a lot

20:30 TimMc: :-)

20:32 ssideris: More importantly, are you sure you need a macro here?

20:32 ssideris: not entirely

20:33 but I'm a bit too much of a clojure newbie to be able to tell

20:34 TimMc: Keep in mind that you can't pass macros around -- because of that, try to make it a function first.

20:35 ssideris: thanks for the tip, but this is an exploration/learning exercise rather than actual development

20:36 so I don't think it matters much

20:36 TimMc: k

20:44 ,(let [f "hello"] `(f ~f 'f ~'f))

20:44 clojurebot: (sandbox/f "hello" (quote sandbox/f) f)

21:56 johnmn3: top'o the eve

22:09 gfrlog: $findfn neg? [-2 -1 0 1 2] [-1 0 1 2]

22:09 sexpbot: []

22:09 gfrlog: is there really no remove-first function in clojure?

22:10 brehaut: gfrlog: asside from the sequence functions like rest and next?

22:10 gfrlog: brehaut: I mean that accepts a predicate

22:11 brehaut: oh right

22:11 TimMc: Presumably he'd also want [3 -2 -1 0 1 2] to return [3 -1 0 1 2]

22:11 gfrlog: (remove-first neg? [3 2 1 0 -1 -2 -3]) => [3 2 1 0 -2 -3]

22:11 I just wrote this, which could be optimized:

22:11 (defn remove-first

22:11 [pred coll]

22:11 (let [[a b] (split-with (complement pred) coll)]

22:11 (concat a (rest b))))

22:12 TimMc: See how I used complement there? ;-)

22:12 TimMc: yup

22:30 brehaut: gfrlog: (defn remove-first [p [f & r :as s]] (if (p f) r s)) ?

22:31 i think i must have still missed something though

22:34 ah i see what i missed. ignore me

22:54 gfrlog: brehaut: I did, but only because I was ignoring the channel as well

22:54 brehaut: gfrlog: its for the best

22:59 gfrlog: ,(cond false true false true true false)

22:59 clojurebot: false

23:00 gfrlog: if I was writing a code obfuscator, that could be a possible substitution for 'false'

23:01 amalloy: gfrlog: ##(condp = true false true false true false)

23:01 sexpbot: ⟹ false

23:02 amalloy: seems harder to read, to me

23:07 gfrlog: ,(doc condp)

23:07 clojurebot: "([pred expr & clauses]); Takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either: test-expr result-expr test-expr :>> result-fn Note :>> is an ordinary keyword. For each clause, (pred test-expr expr) is evaluated. If it returns logical true, the clause is a match. If a binary clause matches, the result-expr is returned, if a ternary clause matches, ...

23:07 gfrlog: always another thing to learn

23:07 amalloy: &(doc condp) ; no truncation!

23:07 sexpbot: ⟹ "Macro ([pred expr & clauses]); Takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either: test-expr result-expr test-expr :>> result-fn Note :>> is an ordinary keyword. For each clause, (pred test-expr expr) is evaluated.... http://gist.github.com/889943

23:14 gfrlog: ,clojure.set/intersection

23:14 clojurebot: #<set$intersection clojure.set$intersection@a14174>

23:14 gfrlog: ,(clojure.set/intersection #{4} [1 4])

23:14 clojurebot: #{}

23:15 brehaut: amalloy: gfrlog how about this for false (apply (fn [a b] (a b)) ((apply juxt (map (fn [length] (comp second #(nth % length))) [27 15])) (filter (comp #{\?} last name first) (seq (ns-map *ns*)))))

23:15 gfrlog: ,(clojure.set/intersection #{2 3 4} [2 3])

23:15 amalloy: gfrlog: use clojure.set on non-sets at your own peril

23:15 clojurebot: [2 3]

23:15 gfrlog: amalloy: I wish it would just blow up

23:15 amalloy: &(doc clojure.set/intersection)

23:15 sexpbot: ⟹ "([s1] [s1 s2] [s1 s2 & sets]); Return a set that is the intersection of the input sets"

23:15 gfrlog: amalloy: did you spend the last few minutes constructing that?

23:16 amalloy: gfrlog: i also changed my name to brehaut

23:16 gfrlog: amalloy: yeah why did he address both of us like that?

23:16 got me all turned round

23:16 amalloy: lol

23:17 brehaut: gfrlog gets confused when we talk about him

23:17 gfrlog: amalloy: brehaut did you spend the last few minutes constructing that?

23:17 brehaut: yes i did

23:17 amalloy: brehaut thinks hand-crafted evil is the same as virtue

23:17 gfrlog: amalloy: brehaut wtf is #{\?}?

23:17 amalloy: gfrlog: a set containing the character "?"

23:17 brehaut: also i realise it should be better if the set in the middle was #{(char (- (Math/pow 2 6) 1))}

23:17 gfrlog: amalloy: brehaut: oh right

23:18 amalloy: gfrlog: srsly you only have to address two people if you're talking to both of them :P

23:18 gfrlog: brehaut: amalloy this is crazy.

23:18 amalloy: oh whoops okay

23:18 brehaut: gfrlog: you were wanting to obfuscate false right?

23:18 gfrlog: brehaut: well not in real life.

23:18 brehaut: but yeah

23:19 amalloy: how about I obfuscate false with ##(not (empty? (clojure.set/intersection #{1 4} [4])))

23:19 sexpbot: ⟹ true

23:19 gfrlog: whoops

23:20 #{4} and [1 4] should do it

23:25 ,(apply (fn [a b] (a b)) ((apply juxt (map (fn [length] (comp second #(nth % length))) [27 15])) (filter (comp #{\?} last name first) (seq (ns-map *ns*)))))

23:25 clojurebot: false

23:34 tomoj: reading the backlog backwards, I am relieved

23:40 gfrlog: tomoj: my apologies

23:56 amalloy: tomoj: filthy habit anyway :)

Logging service provided by n01se.net