# #clojure log - Dec 01 2009

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

0:00 tomoj: if you're using BitSet's destructive operations, clojure can't help you

0:00 dnolen: technomancy: yes, everything working for me now, btw, any opinion on: lein run? not sure if it's a case you're interested in handling the JNI thing.

0:00 perhaps better server as a plugin?

0:00 server -> served

0:01 the-kenny: alexyk: If you store immutable bitsets, ref/agent/atom is perfect for the leaves.

0:05 technomancy: dnolen: I want to add lein run; just not sure how that relates to JNI

0:05 I guess you'd need project.clj to be able to contain a :library-path key or something?

0:06 dnolen: technomancy: just that downloading JNI dependencies is not enough, they need to be unpacked and you can't use classpath to load them, you need to specify the library path when you run the jar with: java -Djava.library.path=foo/bar -jar my.jar

0:07 in order to make Clojure libs use JNIs portable, lein run could help here.

0:07 technomancy: oh, so they're stored in the jar, but they need to be extracted first?

0:07 dnolen: technomancy: unfortunately yes from what I could gather after a whole day of reading people complain about it.

0:07 technomancy: it kind of sounds like having a run command is only a small part of the picture

0:08 alexyk: so I figure there's no bitsets in clojure? :(

0:08 dnolen: alexyk: like setting a bit in a byte?

0:08 alexyk: dnolen: in a series of bytes of any length

0:09 like java.util.BitSet

0:09 dnolen: oh, why not just use that from Clojure?

0:09 alexyk: dnolen: looks like from the above I need immutable one

0:09 hiredman: you don't

0:10 you just shouldn't use clojure's referece types

0:10 technomancy: dnolen: i've gotta take off; will continue this discussion on the mailing list

0:11 dnolen: technomancy: cool, thx much.

0:12 alexyk: hiredman: but then I won't be able to have them inside parallel stuff?

0:13 KirinDave: alexyk: So long as you don't mutate them directly, it's fine.

0:13 alexyk: KirinDave: you set bits on them with (.set myBitSet)... how'd I do it if not directly?

0:14 or perhaps there's a method returning a new bitset there without touching the original

0:15 hiredman: alexyk: you can lock on the bitset

0:15 _mst: alexyk: if you want multiple threads hitting the same BitSet you're either going to need locking or avoid the whole issue by pushing access through an agent

0:16 KirinDave: alexyk: What I mean is, write it in such a way that you copy bitsets and then set them. You don't try and mutate the same one directly.

0:16 Although the performance characteristics of such are beyond me.

0:16 alexyk: ok...

0:16 I probably will do them in threads and then merge

0:37 somnium: not much increase with the new, but only one key cut the time down by half or more. I guess my processing dominates.

0:57 Drakeson: how can I access input args (argv) in a clojure script?

0:57 defn -main doesn't seem to cut it

1:00 oh, nevermind

1:18 qed: how to make a lazy infinite sequence of the sum of [n] natural numbers?

1:19 tomoj: [n]?

1:19 qed: 1+2+3+4+5=15 == the 5th triangle number

1:19 tomoj: I have this in my euler code

1:20 tomoj: oh

1:20 tomoj: well, are you using lazy-seq?

1:20 qed: I was thinking about something like (lazy-seq (iterate..))

1:20 im not sure how to use iterate though

1:21 tomoj: I did it the ugly way with lazy-seq'd recursion

1:21 qed: hmmm, like a loop and recur

1:21 tomoj: (lazy-seq (cons .. ...))

1:21 no recur with that way since it's not tail position, but lazy-seq keeps you from blowing the stack

1:22 somnium: qed: have you googled triangle numbers?

1:22 qed: ([& body])

1:22 what is the & there?

1:22 and what specifically is meant by body

1:22 tomoj: you can carry around extra state by making the function take more than one argument, and then having a no-arg which supplies default values

1:22 body is bound to all the rest of the arguments

1:24 cark: qed: you don't need lazy-seq, i think you should only look at c.c.seq-utils/reductions and iterate

1:24 tomoj: e.g. when looks like ([test & body]), so test is bound to the first argument, and body is bound to a list? all of the remaining arguments

1:24 yeah there's usually a prettier way to do something you're doing with lazy-seq :)

1:25 cark: i think i have the solution right there

1:25 tomoj: looks like body actually gets bound to an ArraySeq

1:25 cark: i so want to give it to you !

1:25 tomoj: never even heard of that..

1:25 qed: sec cark :)

1:26 tomoj: but anyway it's a seq that contains all the rest of the arguments (that's what the & does)

1:26 qed: cark, ah-ha!

1:27 that reductions stuff is slick!

1:27 cark: yes =)

1:27 qed: (reductions + (range 0 10000))

1:27 weee

1:27 tomoj: ?def rec-seq

1:27 qed: re-seq?

1:27 ?def re-seq

1:28 ,doc re-seq

1:28 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/doc

1:28 tomoj: guess c.c.seq-utils uses rec-seq internally?

1:28 cark: that's not an infinite lazy seq

1:28 qed: cark, mine?

1:28 cark: yes

1:28 qed: cark, im guessing you do something where you iterate over (reductions + (range 0 n))

1:29 cark: it's bounded by your range

1:29 tomoj: ,(take 10 (iterate inc 1))

1:29 clojurebot: (1 2 3 4 5 6 7 8 9 10)

1:29 cark: there you go =)

1:29 qed: hehe thanks

1:29 tomoj: that's much prettier than my version

1:30 cark: i guess yours is more efficient tomoj

1:30 cp2: talk more, i am configuring my new irssi theme :)

1:31 tomoj: ,(require 'clojure.contrib.seq-utils)

1:31 clojurebot: nil

1:31 tomoj: ,(doc clojure.contrib.seq-utils/rec-seq)

1:31 clojurebot: "([binding-name & body]); Similar to lazy-seq but binds the resulting seq to the supplied binding-name, allowing for recursive expressions."

1:32 qed: (take n (reductions + (iterate inc 1)))?

1:32 tomoj: I don't understand that at all

1:32 uses an atom for some reason

1:32 cark: ,(take 10 (reductions + (iterate inc 1))

1:32 cark: ,(take 10 (reductions + (iterate inc 1)))

1:32 clojurebot: (1 3 6 10 15 21 28 36 45 55)

1:33 qed: yay

1:33 cark: too bad real world isn't always that nice =/

1:33 tomoj: I love it when you can replace a hunk of ugly unreadable code with a simple one-liner

1:34 qed: now the other thing I need to figure out is how to test this infinite lazy sequence for the number of divisors they have

1:34 tomoj: guess you're doing euler #12?

1:34 qed: yeah

1:38 tomoj: qed: hint: don't prime-factorize

1:38 I tried that and I think it was far too slow

1:38 qed: lol i was just looking at that

1:38 so brute force this portion of it?

1:39 tomoj: maybe if you can quickly prime-factorize it would work

1:40 qed: i dont know how to do that quicly

1:40 quickly

1:41 it seems like the number of the first # of primes is 4, like 2*2*2*2*5

1:41 that's just a guess

1:45 tomoj: hmm

1:45 it seems to be taking quite a long time even with a divisor function I got from, I think, hiredman

1:49 qed: there we go

1:49 user.oO (time (first (filter #(> (divs %) 500) triangles)))

1:49 "Elapsed time: 6931.855 msecs"

1:50 tomoj: wow

1:51 "Elapsed time: 159806.865765 msecs"

1:51 :)

1:51 qed: (def triangles (lazy-seq (reductions + (iterate inc 1))))

1:51 tomoj: if you pasted your divisor function it would make me very happy

1:52 qed: (defn divs [n] (* 2 (count (filter #(zero? (rem n %)) (range 1 (Math/sqrt n))))))

1:52 (time (first (filter #(> (divs %) 500) triangles)))

1:53 tomoj: oh it seems your computer is just way faster than mine

1:53 8gb/ram

1:53 tomoj: netbook here :)

1:53 qed: ah

1:54 tomoj: I think the divisor function I stole from hiredman does the same basic thing, just in a different way

1:54 though your version only took 101s

1:55 qed: my answer is incorrect

1:55 tomoj: huh, strange

1:55 I got the same answer using my divisor function as with yours

1:55 qed: 76576500

1:55 tomoj: that's the answer I got too

1:55 qed: it says incorrect

1:56 this time it worked

1:56 * qed shrugs

1:56 qed: i think i maybe had an extra space

1:56 tomoj: huh, I actually hadn't solved #12 yet apparently

1:57 though I had the code right here to do it in 159s, strange

1:57 qed: ive been avoiding it

1:57 cause it seemed boring

1:58 so does 21

1:58 tomoj: cl-format probably makes #17 trivial

1:58 if cl-format does ~r

2:00 qed: unfortunately thats all the euler ill be doing for tonight

2:00 im gonna try to wake up early before work and do one

2:00 i do better work in the AM

2:01 gnight all

2:02 tomoj: ah crap

2:02 euler wants british english numbers and cl-format does something else

2:07 I wonder if euler did that on purpose so we couldn't use CL's ~r

2:08 qed: it inspires debate

2:10 tomoj: i should qualify that i lifted chouser's #12 divisor function to finish that off

2:20 tomoj: oh, hmm

2:20 did yours say "totally useless"?

2:20 I thought it was hiredman's but my memory is totally shot

2:21 oh, yours was different, I forgot. see, my memory is _totally_ shot

2:21 don't do drugs, kids

2:26 hiredman: if I recall, euler just wants a word count

2:27 I think I just did the first letter in each word, then counted those

3:08 angerman: how do I create an agent with meta-data?

3:09 (with-meta (agent nil) {:no 1}) gives me an Agent cannot be cast to IObj Exception

3:10 hiredman: there are two seperate metadata protocols, bifibricated on mutability

3:11 _ato: ,(doc reset-meta!)

3:11 hiredman: with-meta is for metadata on immutable things

3:11 angerman: meh :( using (agent nil :meta ....)

3:11 so (with-meta) is immutable

3:12 hiredman: it is for returning a new immutable thing with metadata attached

3:12 _ato: yes with-meta is for immutable objects, use alter-meta! or reset-meta! to change metadata on mutable objects (like refs, agents, toms, namespaces etc)

3:13 angerman: yep, I was just confused, I wanted to setup the agent with metadata upfront, musst have missed the :meta arg

3:14 I'm trying to write an agent pool that dequeues on completion.

3:15 e.g. I have a list of tasks, and 4 agents. Now I could spread out the tasks to the agents randomly. But as the tasks may vary in computation time. That could end up having one agent work very long while the others are waiting.

3:15 I think using watches would be even better.

3:34 does the function that the agent executes have any access to the agent?

3:43 slashus2: angerman: Are you talking about *agent* ?

3:46 angerman: slashus2: maybe, let me see

4:45 wheee ...

5:28 optimizer: is using a c++ ffi even practicel in clojure, or is the jni calls just too expensive?

5:29 ambient_: well i'll get back to you, im doing that right now

5:29 optimizer: my question?

5:29 ambient_: rtaudio has no good jni implementation :/

5:30 optimizer: dude

5:30 i wnat to do audi processing too

5:30 any chance you ca open source your interface?

5:30 ambient_: well there's jass-sdk

5:31 it seems to be pretty low-latency and includes synth toolkit, but i don't know how current it is

5:57 fliebel: hiredman: After some reading I finally understand you snippet you gave me yesterday. That empty string and the double %S at the start drove me mad, until I carefully read the doc and tried leaving them out. Thanks, I'm on my way to write something working now! :)

6:12 angerman: do defn's share any state?

6:13 ohpauleez: I'm not sure exactly what you mean, but they'll only share some notion of state in a binding form

6:13 angerman: I'm trying to understand why http://gist.github.com/246232

6:13 throws an IllegalStateException: No transaction running

6:14 the function is sent to an agent to process it.

6:16 ohpauleez: let me take a look

6:17 Chousuke: you have alters in there

6:17 ohpauleez: you have alters

6:17 and they need to be in a dosync

6:17 with atoms

6:17 ahhh Chousuke! you beat me to it

6:18 angerman: thanks, let's see

6:19 ohpauleez: angerman: because atoms are allowed to be manipulated by multiple threads, you need to put them in a dosync to operate on them with alters http://java.ociweb.com/mark/clojure/article.html#ReferenceTypes

6:20 same with refs

6:20 Chousuke: angerman: probably the man, mix and avg values be strings is not very performant

6:20 angerman: ok, but the atom is function local, right?

6:20 Chousuke: angerman: that'll create *lots* of strings if you have many query results :/

6:20 ohpauleez: I mean refs, not atoms

6:20 angerman: Chousuke: it's a database -> libsvm conversion.

6:21 so I need the strings and write them out

6:21 Chousuke: angerman: yeah, but you should accumulate values and create the strings at the end

6:22 angerman: I get for each row three float values

6:22 that need to end up as <i>:<float value> <i+1>:<float value> ....

6:22 so I'll create the <i>:<float values> in an accoumulator and run reduce over them?

6:23 Chousuke: no, just accumulate the float values into a vector and print the contents of the vector (using format) instead of creating temporary strings? :)

6:23 fliebel: Can someone explain me doseq? I read map is for changing the list, but I just want to call a function with every item. I changed map into doseq, but it does not work.

6:24 angerman: Chousuke: hmmm....

6:24 Chousuke: fliebel: (doseq [item seq] (function item))

6:24 fliebel: and map doesn't *change* anything :)

6:24 well, shouldn't.

6:25 fliebel: Chousuke: Ok, map is for returning a new sequence with different items, right?

6:25 Chousuke: yeah.

6:26 angerman: Chousuke: so basically i conj them onto a vector.

6:26 fliebel: Chousuke: Why does doseq have this strange syntax? I thought it would work on a sequence and put the items in a anonymous function and use %.

6:26 angerman: (alter vec conj floatval)

6:27 then I have a vector of floatvals, how do I turn that into a string with format? that vector is going to be 44700 items long

6:28 Chousuke: do you need a single string? :P

6:29 can't you just print it out an item at a time

6:29 also, now that I think about it, why do you have refs in that function at all?

6:29 fliebel: Why doesn't this work? (doseq [tag [:a :span]] (def tag (partial html tag))) Apparently Clojure confuses me quite a lot...

6:29 angerman: because the values are in a column in the table and I need them as a row in the file

6:30 Chousuke: fliebel: html is a macro? :)

6:30 angerman: so I'm iterating over the rows, collecting the data, and writing it out.

6:30 fliebel: Chousuke: A function at least....

6:30 Chousuke: angerman: so don't write newlines?

6:30 angerman: well the writer-agent adds a newline

6:31 Chousuke: you'll need to change it.

6:31 angerman: I have 253 experiments, with each 44700 features with min/avg/max values

6:31 Chousuke: creating a string of all the 45 thousand float vals is going to waste a huge amount of memory.

6:31 you don't want to do that.

6:32 fliebel: Chousuke: html takes a tag, attributes and content, and I want to make a function that will define a few partial functions with the tag already supplied.

6:32 angerman: assuming I'm going to collec the 44700 values in a vector, I could hand that vector to the writing agent

6:32 Chousuke: possibly

6:32 angerman: and let the writing agent work them off in a print loop

6:32 Chousuke: fliebel: oh right.

6:32 the def is the problem

6:33 defs are only for top-level

6:33 you need a macro :)

6:33 fliebel: ok… and is it a problem to supply :a instead of a? I'm still not sure what it means to write a :a or "a"

6:34 The final goal is to make it a macro, but I blow everything everytime it try, so I thought I'd start off with a function.

6:34 Chousuke: ,(let [a 1] (map class [a 'a :a "a"]))

6:34 clojurebot: (java.lang.Integer clojure.lang.Symbol clojure.lang.Keyword java.lang.String)

6:35 ohpauleez: fliebel: :a is a keyword

6:36 Chousuke: I can't stay to help, though. must hurry.

6:36 I'm here, I'll pick things up

6:36 fliebel: ohpauleez: thanks :)

6:37 ohpauleez: fliebel: totally welcome, that's a great resource, you can learn the bulk of Clojure in a day from it

6:37 angerman: are you all set?

6:37 fliebel: I just read half of it yesterday… But in a kind of sleepy and back-and-forth way :P

6:38 ohpauleez: fliebel: are you coming from Java, Python/Ruby, Common Lisp/Scheme or relatively new to programming?

6:39 fliebel: I started of with Java, then did PHP for a while, a few months ago I started doing Python and now I'm starting Clojure. But you can see me as a Python guy because it's more recent than Java and I like it better.

6:42 ohpauleez: So keywords in clojure are cool. http://clojure.org/data_structures#toc8

6:42 fliebel: I find it quite hard to learn Clojure… Where in PHP, Javascript and Python I have to think about whether or not to use curly branches or to use count or length or whatever or if I need to make an array, a map or a dict. With Clojure I have to think fundamentally different.

6:43 ohpauleez: you use them as you would standard keys of a dictionary

6:43 fliebel: keywords are the : ones?

6:43 ohpauleez: except, like python, hash-maps (dictionaries), are used for book keeping and tracking a lot of information

6:44 fliebel: yep, : ones

6:44 fliebel: I read they are like strings, but more like a number, every time you type :a or 1 you get the exact same thing.

6:45 ohpauleez: yes, they evaluate to the themselves

6:45 fliebel: so what are those ' things chousuke mentioned?

6:45 ohpauleez: quoting a symbol

6:46 have a look at: http://java.ociweb.com/mark/clojure/article.html#Syntax

6:46 fliebel: ah, just like qupoting a list '(:a 'b c 1)

6:47 I know the quoting syntax… Just that the context was missing.

6:47 ohpauleez: right, you quote a symbol so the reader doesn't attempt to evaluate it

6:47 fliebel: so what is the difference between ' and ? Quite confusing if you ask me...

6:47 ambient_: optimizer: i got jrtaudio working, just had to edit some .cpp and makefiles. http://code.google.com/p/jrtaudio/

6:48 _ato: ,inc

6:48 clojurebot: clojure.core/inc

6:48 _ato: ,'inc

6:48 clojurebot: inc

6:48 _ato: difference 1:  qualifies the symbol with its namespace

6:49 ,(:a ~(+ 1 1))

6:49 clojurebot: (:a 2)

6:49 _ato: ,'(:a ~(+ 1 1))

6:49 clojurebot: (:a (clojure.core/unquote (+ 1 1)))

6:49 _ato: difference 2:  lets you "unquote" in the middle of a form, so you can selectively evalute stuff

6:49  is usually used for writing macros

6:50 ohpauleez: thanks _ato, I was only going to mention #2

6:50 fliebel: I noticed that, but in which case would you want to use ' instead?

6:50 .(:a :b)

6:50 ,(:a :b)

6:50 clojurebot: (:a :b)

6:51 fliebel: ,'(:a :b)

6:51 clojurebot: (:a :b)

6:51 ohpauleez: I use ' all the time unless I'm writing a macro and need evalutation via unquoting

6:51 fliebel: Ok, not for any practical reason or something like that...

6:51 _ato: ' is faster in certain cases, and sometimes you don't want the symbol qualified

6:51 fliebel: true...

6:51 _ato: ,'(a (b c))

6:51 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/a)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/b)) (clojure.core/list (quote sandbox/c)))))))

6:52 fliebel: Whoa! what happened?

6:52 _ato: ~ping

6:52 clojurebot: PONG!

6:52 _ato:  supposorts something called splicing-unquote, which looks like this: ~@

6:53 ,(a b ~@[:c :d] e f)

6:53 clojurebot: (sandbox/a sandbox/b :c :d sandbox/e sandbox/f)

6:53 _ato: to do that splicing it needs to rebuild the list

6:53 ohpauleez: fliebel: it's like *args in pything

6:53 python*

6:53 _ato: that's where all that stuff comes from if you do '(something) and is why ' can be faster

6:54 fliebel: ohpauleez: finally an explanation of that splicing thing....

6:55 Can I use that splicing thing everywhere, or do I need to use apply or something like that?

6:55 _ato: you can only use it inside a syntax-quoted  form.

6:55 ,~@foo

6:55 clojurebot: java.lang.Exception: Unable to resolve symbol: foo in this context

6:56 _ato: ,~@2

6:56 clojurebot: java.lang.IllegalStateException: Var clojure.core/unquote-splicing is unbound.

6:56 fliebel: I see...

6:57 _ato: sure

6:57 angerman: Chousuke: thatnks, that seems to work way better

6:57 fliebel: Ah, I forgot: "Don't als to ask"

6:58 Can I turn :a into a?

6:58 ohpauleez: angerman: glad it's working out

6:59 _ato: ,(symbol (name :a))

6:59 clojurebot: a

6:59 fliebel: ato: How intuitive :)

6:59 ohpauleez: ,(doc name)

6:59 clojurebot: "([x]); Returns the name String of a symbol or keyword."

7:00 _ato: ,(keyword (name 'a))

7:00 clojurebot: :a

7:00 fliebel: ,(doc symbol)

7:00 clojurebot: "([name] [ns name]); Returns a Symbol with the given namespace and name."

7:01 fliebel: I'll try to write my macro now, but I'm sure it will not work the way I planned it.

7:01 ohpauleez: fliebel: You can use the doc browser on your clj REPL for everything. If you sit in here for a few days and doc everything that people talk about and play with it on your own REPL

7:01 you'll be up and running in no time

7:02 fliebel: Hmmm, good idea.

7:05 (defmacro deftag [tag]

7:05 (def ~(symbol (name tag)) (partial html ~tag)))

7:05 It works, but now I need to get it working with multiple arguments.

7:06 like… (deftag :a :span :p)

7:10 ato or ohpauleez: How can I make a macro that returns the second line of my code for every argument? You said def is only for the top level, so I can't put it in some sort of loop, can I?

7:15 rhickey: fliebel: just have the macro emit the defs in a do - the do will disappear at top level

7:16 fliebel: rhicky: The number of arguments is unknown, I want to use the & argument syntax. Would loop work as well?

7:16 ohpauleez: fliebel: also, have a look at http://en.wikibooks.org/wiki/Learning_Clojure#Macros

7:16 [& args]

7:17 [arg-one arg-two & other-args]

7:17 rhickey: fliebel: see the definition for declare in core.clj

7:19 fliebel: I got this now, but it fails...

7:19 (defmacro deftag [& tags] `(loop [tags tags] (def ~(symbol (name (first tags))) (partial html ~(first tags))) (recur (rest tags))))

7:19 ohpauleez: There is also a little bit of info on declare here: http://java.ociweb.com/mark/clojure/article.html#DefiningFunctions

7:20 rhickey: ,(macroexpand-1 '(declare a b c))

7:20 clojurebot: DENIED

7:20 rhickey: aargh

7:20 expands to: (do (def a) (def b) (def c))

7:21 fliebel: rhickey: that sounds like what I need…

7:22 ohpauleez: also, your loop has two args, but you're only recuring one

7:22 rhickey: fliebel: read the source to declare until you understand it, and remember macros are about taking some code and turning it into other code, not doing things

7:22 ohpauleez: and it might not make sense for this to be a macro

7:23 exactly what rhickey said

7:23 you only use a macro when you don't want to eval all the args

7:23 fliebel: uuuhm, that sound reasonable...

7:23 ohpauleez: it's for generating other syntax or conditional controls

7:25 fliebel: I want people to be able to call (a rest) instead of (html :a rest) by defining a as a partial.

7:25 so all i want to do is some easy way to define a few of those partials in one blow.

7:26 ohpauleez: I would define a with-html macro maybe

7:26 I'm not sure what you're building

7:26 but (with-html "some-file.html" (my-body-here))

7:27 I assume some html browser or DSL

7:27 fliebel: DSL...

7:32 But I guess it would be a valid macro to turn a list of keywords to a list of partial statements...

7:37 I have to leave, bye!

7:56 cemerick: rhickey: what's your snap reaction to the notion of a string interpolation reader macro? e.g. #@"str of some value @here", or somesuch.

7:56 rhickey: cemerick: ick

7:56 cemerick: I'm writing (format ...) *way* too much IMO -- am about to go write a userspace macro to do string interpolation, but I thought I'd float the reader macro idea.

7:56 heh, OK

7:58 rhickey: but I'm not saying never, just the ones I;ve seen were more complex than the problem they were 'solving'

7:58 cemerick: rhickey: Sure. I think it's somewhat inevitable. Too handy in ruby to not steal.

7:58 rhickey: (str "str of some value " here)

7:59 cemerick: well, short stuff is certainly not where the money is

8:00 writing long-ish dialog box msgs with lots of bits of data scattered about, webby content generation stuff that doesn't warrant a real templating engine, etc...that's where the real pain is.

8:01 _ato: (str "Hello, " user "! You have " (count tasks) " remaining tasks.")

8:01 vs ala ruby "Hello, #{user}! You have #{(count tasks)} remaining tasks."

8:01 chouser: ruby's is pretty simple, isn't it? And could be done with a simple fn (or macro) wrapping a normal string I think.

8:01 _ato: I don't think your gaining much

8:01 cemerick: chouser: yeah, I'm half-done with a userland macro

8:01 ruby does allow arbitrary expressions, which is a little nutty

8:02 _ato: the two are *very* different w.r.t. readability IMO

8:02 chouser: oh, I thought that was the whole point, the arbitrary expressions.

8:02 nested even, which can get fun.

8:04 cemerick: Even simple references to existing bindings would be a win at the moment.

8:04 but even nested arbitrary expressions should be pretty straightforward

8:05 chouser: only problem there would be double-quote-escaping, I think.

8:06 cemerick: yeah. Having two string delimiters is super-handy.

8:06 " *and* ', that is

8:07 chouser: I meant that this is valid ruby, but Clojure won't read it right: "outer #{"this" + " inner #{10 + 20}"}"

8:08 _ato: it does beat (format "Hello, %s! You have %d remaining tasks." user (count tasks))

8:08 cemerick: chouser: oh, I didn't realize that was allowable -- I thought people just used single-quotes for strings in #{} out of necessity (rather than style/readability)

8:10 ambient: i got (gen-class :methods [[callback [double<>] Integer]]) double<> doesn't seem to work, im trying to say to clojure that the type is double[]

8:11 so which is the right way to tell gen-class that the methods input attribute is of type double[]? :/

8:11 chouser: ambient: I think for gen-class you still have to use "[D"

8:11 ambient: oh ok

8:13 *lang

8:14 chouser: ambient: :-( http://www.assembla.com/spaces/clojure/tickets/162

8:15 ambient: chouser: ok seems i have to update clojure :)

8:15 using 1.0.0 currently

8:15 chouser: ambient: that fix isn't in github anywhere yet

8:15 ambient: :(

8:15 well guess im screwed then

8:16 chouser: ambient: you could try applying it to your 1.0.0 clojure -- there's a passing chance it might work.

8:16 ambient: here's the code fwiw: http://paste.pocoo.org/show/154098/

8:17 chouser: ambient: or you could go crazy and move right to the "new" branch and use deftype instead.

8:17 ambient: i'd rather not :D

8:17 chouser: ambient: very sensible.

8:18 rhickey: anyone have any luck with latest deftype/reify/protocols?

8:18 chouser: rhickey: haven't had a chance to do much yet. maybe this afternoon.

8:20 rhickey: I'm thinking about incorporating chouser 's suggestion to drop the parens on multiple arity in defprotocol, and move to defprotocol style of P1 (m1 ...) (m2 ...) P2 (m3 ...) (m4 ...) in deftype and reify, vs the [P1 P2] (m1 ...) ... (m4 ...)

8:21 the latter makes the simplest case simpler still:

8:21 (reify ActionListener (actionPerformed [this evt] ...))

8:21 and makes deftype/reify consistent with extend*

8:22 cemerick: rhickey: willl that still transparently work with overlapping interface sigs?

8:23 rhickey: cemerick: yeah, just put in either, for now would just turn this into old style under the hood, but moving forward could do more checking with them broken out

8:24 cemerick: rhickey: This should probably be an error: (reify P1 P2 (m1 ...) (m2 ...) (m1 ...))

8:24 rhickey: incorporating pile-o-methods into syntax means marrying pile-o-methods semantics

8:25 cemerick: yes, should be

8:25 haven't coded it yet

8:25 cemerick: sure

8:25 rhickey: although sometimes code-generating-code writes things like that

8:25 cemerick: The pile-o-methods approach seems like a lot less work to me. Probably makes things hell for VM and language implementers, though.

8:26 rhickey: cemerick: you've never gotten bitten by wanting to derive from 2 classes/interfaces whose methods clash?

8:27 cemerick: rhickey: I try to make sure I'm building the libraries, not using them. :-) Though that's changing fast...

8:27 chouser: you can namespace-qualify the method names in reify and deftype now?

8:27 rhickey: chouser: no

8:27 chouser: so splitting them by protocol name would help there, right?

8:28 rhickey: chouser: without being able to generate prefixes, the resulting JAva class is going to mash them together anyway

8:29 but having them split in the syntax means prefixes might be a future possibility

8:29 chouser: ok

8:29 rhickey: also, enhanced checking

8:29 and consistency with extend*

8:29 and simpler simplest case

8:31 I have to say, adding all the explicit thises to the few exisitng reify/deftypes was a real, seeming pointless, pain

8:31 started using _ for this

8:31 will be most common case

8:32 :(

8:32 chouser: that's actually what I was tripping over last night too. Used 'x' instead of 'this' in my defprotocol, and was then confused...

8:32 rhickey: the first arg will rarely be used

8:33 rhickey: almost made me want to accept with and without '.'

8:34 chouser: hm, surely not.

8:34 rhickey: chouser: yeah, the only time you need this is to call another method on yourself or pass this to someone else

8:34 chouser: passing idea :)

8:34 now gone

8:35 chouser: you don't want to use 'this' in the defprotocol anyway, that name is for consumers, who will be calling the protocol fn and passing what they consider a coll or num or something

8:36 this is a name for an implementor

8:36 chouser: extend takes real fns with a real first arg, and calls pass in a real first arg. in all other cases the body isn't a real fn, right?

8:36 rhickey: chouser: right

8:37 extend*

8:37 chouser: for me, that's the consistency pain point.

8:39 and the extend macros could hide the 'this' arg as well. hm...

8:39 rhickey: but how to mitigate? would just make members more cumbersome (foo [this x] ... (:afield this))

8:39 chouser: they would have to auto-bind 'this' though, since you will need it in extend-* defs

8:40 no implicit fields

8:41 doing implicit this in deftype/reify and extend-* would make everything consistent (don't supply frst arg) *except* pure extend and mixins

8:42 the latter being more power tools

8:42 chouser: right, the latter is what I was suggesting, not (:afield this)

8:43 rhickey: I see the vast majority of people using deftype/reify and extend-*

8:43 chouser: still a slight mismatch with callers, but maybe that's no too bad?

8:43 rhickey: but it is still a mismatch with defprotocol itself

8:44 esj: guys: I'm having a 'use' issue - can anybody tell my why (use 'clojure.contrib.lazy-seqs) works, but (use 'clojure.contrib.json.write) returns java.lang.NoClassDefFoundError (NO_SOURCE_FILE:0). I have just pulled Master from git. Sorry to bother you with this.

8:44 chouser: rhickey: because you want to allow a name other than 'this'?

8:44 rhickey: chouser: because the arg is there

8:45 chouser: esj: no need to apologize. :-)

8:45 rhickey: with deftype/reify of interfaces it's easy since the interface method declaration doesn't include this

8:45 esj: try ant clean on contrib before rebuild

8:46 esj: rhickey: on it

8:47 rhickey: so, declare Seqable.seq(); , define seq(){...}, call coll.seq(), all matches (in the parens)

8:48 but (defprotocol Seqble (seq [coll]) ), (deftype Foo Seqble (seq [] ...)), (seq afoo) doesn't match

8:49 chouser: I still don't see why defprotocol can't have an implicit coll (names 'this' of course)

8:49 rhickey: could be (defprotocol Seqble (seq []) ), (deftype Foo Seqble (seq [] ...)), (seq afoo) ; protocols presume first arg

8:50 chouser: named

8:50 right

8:50 leaving (seq afoo) the odd man out

8:50 rhickey: I think people get that after: coming from Java, using Clojure and seeing where target goes in (.method target args)

8:51 but not intuitive, and bigger mismatch with extend/mixins

8:51 chouser: running the kids to school -- brb

8:55 fliebel: How can I append to a list? conj only prepends things… To me lists are a lot more complicated than the regular Python square bracket syntax. I'm also still at a loss on how I can insert at a specified index.

8:56 esj: fliebel: I had the same misunderstandings - seqs are totally different from vectors

8:56 ambient: python lists aren't even lists afaik, they're dynamic arrays

8:57 esj: fliebel: you _can_ append to seqs, but I think that it, in general, is not a good idea.

8:58 fliebel: esi: Is there any good documentation on vectors, lists and maps? http://clojure.org/sequences is not very helpful to me.

8:59 rhickey: fliebel: http://clojure.org/data_structures

8:59 esj: zakly

9:00 rhickey: after git pull, ant clean, ant on clojure and clojure-contrib my error is now (use 'clojure.contrib.json.write)

9:00 java.lang.NoSuchMethodError: clojure.lang.RestFn: method <init>()V not found (NO_SOURCE_FILE:0). Seen it before ?

9:01 rhickey: that is almost always a mismatched/incomplete build problem

9:01 leafw_: fliebel: I'd use vectors wherever you think "list"

9:01 esj: fliebel: also check out http://blip.tv/file/707974 I found it really useful

9:02 fliebel: leafw: How about appending a statement to a function? functions are lists in fact, aren't they?

9:02 esj: rhickey: thanks - I'll hunt it down.

9:05 fliebel: esi: How can I append to a list? Or are there any other options to append a statement to a function?

9:06 esj: fliebel: are you working with macros ?

9:06 fliebel: esi: sort of… just playing around, but for this example that includes using a macro.

9:07 At least the function is in list state, not executed.

9:11 esj: fliebel: OK, I haven't delved as deep as macros yet - so probably not much help. When I was trying to fight Clojure by appending to a seq I made a function that traversed the list manually, synthesising an append. But it was a silly thing to have done.

9:12 fliebel: I can imagine… I'll try something else, and continue to do that until I understand Clojure, or at least macros

9:12 rhickey: fliebel: there is concat

9:13 Drakeson: can I access the name of the ns that uses my library, in a macro?

9:14 rhickey: Drakeson: *ns*, at macroexpansion time, will be that ns

9:15 rfgpfeiffer: reify does not complain when I do not implement all methods in a protocol. Is this the intended beaviour?

9:15 Drakeson: thanks :)

9:16 rhickey: rfgpfeiffer: that is intended, but an open question moving forward

9:17 esj: rickey: totally correct, got it going now, thanks.

9:19 rfgpfeiffer: rhickey: i'd like it to produce a warning, but not an exception

9:20 chouser: warnings need a way to be turned off

9:20 rfgpfeiffer: like in haskell when your patterns do not cover all possbile cases

9:22 rhickey: rfgpfeiffer: that would be possible, I think we need to see how often that 'feature' is leveraged

9:22 rfgpfeiffer: at least once :)

9:23 rhickey: I mean the 'isn't it great I don't have to implement all the methods since I know they won't be called' feature

9:29 rfgpfeiffer: haskell-like pattern matching with double dispatch on protocols http://gist.github.com/246310

9:30 lpetit: rhickey: use case. clojure.core defines some protocol. I create an implementation of this protocol. Later a function is added to the protocol. Nothing warns me I'm then not totally compliant with the new version of the protocl

9:30 oh, and hi, BTW :)

9:31 rhickey: lpetit: I'm not strenuously arguing against a warning, but one person's warning is another's nuisance

9:31 lpetit: rhickey: certainly, and that would let room for implementing those needed warnings in IDE :-p

9:32 rhickey: experience will show what the default should be

9:32 rfgpfeiffer: what about a variable *warn-on-non-exhaustive-protocol-implementation*

9:32 rhickey: rfgpfeiffer: something like that but, ... shorter

9:32 rfgpfeiffer: of course

9:34 rhickey: any more opinions on implicit this in deftype/reify/extend-type and extend-class?

9:35 lpetit: "experience will show what the default should be" :-p

9:36 rhickey: lpetit: for implicit this? not toggleable

9:36 my brief experience was a lot of _s

9:37 lpetit: rhickey: _s are an interesting information by itself for code readers, aren't they ?

9:38 hoeck: rhickey:

9:39 rhickey: lpetit: dunno - seems like noise and tedium to me: http://github.com/richhickey/clojure/commit/a84a4e1ff36b85ec2afa4df41c5affca1a76c78a

9:40 hoeck: rhickey: I'm on the new branch from nov, 12 and actually like the implicit this in deftype after implementing some clojure interfaces

9:41 rhickey: hoeck: I agree, when implementing interfaces it is clearly better. we've been discussing how to make it fit better with protocols, which currently declare that first arg

9:41 hoeck: rhickey: explicit this would clutter the code as in your examples, mostly I'm accessing some fields without using this or call the types ctor

9:41 rhickey: a,h ok

9:41 rhickey: hoeck: right, 'this is rarely used

9:41 lpetit: rhickey: feedback from python guys may be interesting (isn't explicit this/self the enforced default in python ?)

9:42 rhickey: lpetit: I found 'self' annoying in Python

9:42 chouser: me too

9:42 fogus: here here

9:42 chouser: though I was a different programmer then

9:43 angerman: isn't self only a convetion?

9:43 lpetit: rhickey: so maybe you have already the answer => implicit this (or toggleable, but wouldn't it be even worse than just acting it's implicit, period ?)

9:43 rhickey: the crux of the matter is, given (defprotocol P (foo [x] ...)), what will you expect to write in (deftype T [a b c] P (foo ...

9:44 chouser: I think I'd want it gone from defprotocol too.

9:44 rhickey: then, as consumer of P, wanting to call (foo ...) , will expect to pass what?

9:46 chouser: (foo a-P named args here) ... right? That is the only remaining mismatch (besides direct use of extend fn). So the question is, is that mismatch acceptable.

9:47 rfgpfeiffer: i like self in python, but reify is more static than python's class:

9:49 rhickey: chouser: the doc string for foo could add the param back in

9:50 chouser: rhickey: that would certainly help.

9:50 rhickey: foo ([Protocol arg arg]) docs

9:52 chouser: there is a conceptual tension between these things being functions and being methods. When called, they're *really* like functions. When defined in deftype, *really* like methods.

9:52 cburroughs: angerman, The name 'self' is a convention, but the argument must be there.

9:53 chouser: so we're pushing around where to draw the line between method-like defaults and function-like behavior.

9:54 rhickey: There might also be a problem with adding implicit this in extend-type/class, in that those are *not* methods, won't have access to fields etc, and *will* be closures

9:54 chouser: having the first arg not show up only in the calls (and arglists metadata) is one extreme. Explicit this all the way down is the other extreme.

9:55 rhickey: of course, reify methods are not functions but *are* closures

9:56 something about having the target as an arg in extend-type/class makes it clearer these are external extensions

9:56 chouser: explicit this everywhere does have the benefit of complete uniformity.

9:57 rhickey: also, implicit this in reify isn't really acceptable, only named this (reify this P ...) because reify likely to be nested/macro-wrapped

10:00 chouser: [_] vs [] is a bit ugly, but hardly a huge cost.

10:01 rhickey: one tension is that interface declarations already take a stand that can't be changed

10:01 so when implementing an interface the _ is extra, often forgotten baggage

10:03 a common problem for people with gen-class

10:03 chouser: but that's interop :-)

10:07 rhickey: another wrinkle:

10:07 (defprotocol P

10:07 (foo [x]))

10:08 (deftype Foo [a b c] [P]

10:08 (foo [x] (recur 42)))

10:08 java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 1

10:08 octe: (let [agents (map (fn [&args] (agent 0)) (range concurrent))] <- there has to be a better way.

10:09 chouser: rhickey: :-(

10:09 rhickey: recur works, but you can't replace this

10:09 chouser: right

10:10 octe: (take 10 (repeatedly #(agent 0)))

10:10 rhickey: hmm, someone proposed an n arg to repeatedly to match repeat...

10:10 chouser: octe: (for [_ (range 10)] (agent 0))

10:11 octe: thanks.

10:12 rhickey: (extend-class String P

10:12 (foo [s] (recur)))

10:12 java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 0

10:14 there will be no way to make the same arglist and recur call work in both deftype and extend-type

10:14 indicates they should have different arglists

10:15 octe: http://paste.lisp.org/display/91345 <- should that work?

10:15 it seems to sometimes give errors

10:16 chouser: rhickey: proxy currently has the same problem.

10:16 octe: or maybe it's only sometimes if the agent function hasnt run yet..

10:16 chouser: octe: that usage of #() is incorrect

10:16 rhickey: chouser: because proxy's implicit this is a lie

10:17 chouser: rhickey: right

10:17 octe: chouser: how?

10:17 rhickey: not so for deftype/reify

10:17 more tea needed - biab

10:19 chouser: octe: #(foo) calls foo, so it's like (fn [] (foo)). you're trying to call println but actually calling the return value of (println "hi") which is always nil

10:19 ,((println "hi") nil)

10:19 clojurebot: java.lang.NullPointerException

10:20 chouser: octe: also, agent action fns must take at least one arg, the current value of the agent.

10:20 octe: so try (send a (fn [_] (println "hi") nil))

10:21 octe: chouser: i don't understand the #() macro, does it take as many arguments as you actualyl use in the function?

10:21 chouser: octe: yes

10:21 well, as many as the highest you name.

10:21 djork: would it make sense to use an agent to process a line of input from a socket?

10:22 chouser: ,(#(println "4th is" %4) :a :b :c :d)

10:22 clojurebot: 4th is :d

10:22 djork: like, say the agent's value held the sockets to read/write on

10:22 chouser: djork: yeah, that will probably work.

10:22 djork: blocking is not a problem?

10:23 because it could wait indefinitely

10:23 right now I'm using refs

10:23 chouser: djork: blocking is fine as long as you use send-off

10:23 djork: ah, I see

10:23 octe: chouser: so, (send a #(println %1)) would work too?

10:23 for example

10:23 chouser: octe: yes, but of course will change your agent state to nil

10:24 octe: yes, what i want to do is a one-off asynchronous task

10:24 don't know if an agent is correct for that

10:24 chouser: octe: it might be. You might also like 'future'

10:25 hm, actually if it's one-off, agent is probably not right.

10:25 djork: future sounds perfect

10:25 although deref'ing the returned future blocks

10:25 so you'd be responsible for managing the time in-between

10:26 but that only matters if you care about the result

10:27 octe: do not care about the result

10:27 did not know about future, sounds better :)

10:28 djork: anybody else notice that JLine doesn't handle ^Y (yank or "paste")...?

10:28 chouser: I use rlwrap

10:29 djork: hmm

10:29 octe: i don't get prints from my agents/futures in my *slime-repl clojure* buffer, i seem to remember that there was some setting that fixed that

10:29 djork: that sounds better

10:29 octe: sound familiar for anyone?

10:29 djork: octe: it's probably a slime thing

10:29 octe: yes

10:29 chouser: I think they go to an inferior buffer, whatever that means.

10:29 octe: ah, yesh

10:30 just need to find the variable..

10:30 fliebel: Can I use future on the repl? It just waits until the output is returned because the return value is printed of course.

10:31 chouser: fliebel: yes. maybe stuff it in a 'def' if you don't want to wait just yet.

10:31 djork: chouser: thanks for the rlwrap tip, works great

10:32 * djork nukes jline

10:32 octe: M-x slime-redirect-inferior-output

10:32 if someone else was curious

10:32 i find the public irc log for this channel a great help when searching for problems :)

10:32 i mean solutions to problems..

10:33 djork: oh wow, rlwrap has parens-matching, that is really killer

10:33 chouser: octe: you use google on it?

10:33 djork: and vi-keybinding support. mmmmm

10:33 fliebel: chouser: works...

10:33 djork: nice

10:33 octe: chouser: yep

10:34 chouser: octe: good. that's the intended use case. glad it's working for you. :-)

10:35 lpetit: rhickey: I don't mind having to repeat the explicit "this" in recur either, since I expect the default programming model will be to compose functions into maps , so that "adding external behaviour" might be the standard. (but maybe this <- whole sentence did not make any sense ?)

10:38 rhickey: lpetit: in deftype and reify it's not a matter of repeating - you have to leave it out

10:39 lpetit: it will be interesting to see how much mixing in there will be - mixins are not an option inside deftype/reify

10:41 fliebel: (What are these thing? I'm trying to (doc) everything, but this gives: Unable to resolve symbol: deftype in this context)

10:41 rhickey: could be possible in deftype

10:42 but not reify, as closure-per-method in reify reintroduces the n-object-per-object overhead of proxy

10:42 chouser: fliebel: these are experimental features in the "new" branch on github

10:43 Raynes: Incidentally, I just google the questions. If there is something relevant in the IRC logs, it is likely to be at the top of the results.

10:43 fliebel: chouser: that explains quite a lot...

10:44 chouser: fliebel: you're watching the Clojure design and implementation process in action.

10:45 fliebel: chouser: Cool, but I do not yet understand the basics...

10:45 lpetit: rhickey: I guess I'll have to grok again the current state of the defprotocol / deftype wiki pages. But from where i'm, right now, all this seems a little bit complex to remember. So I would not be against "radical" choices (if possible) that would make the rules clear, the rule list short, and let people macroify things where they are tired of typing too much ...

10:47 rhickey: lpetit: I understand, but if the simplest rule is, say, explicit this, and everyone hates it and ends up using their own macro, that's a fail

10:49 octe: is it a good/bad idea to queue up a bunch of functions with send-off to agents?

10:49 lpetit: rhickey: sure, but if the rules are more specialized for each use, and everyone hates when he/she has to add a protocol or reify something, ...

10:49 rhickey: lpetit: thus, getting it right is important

10:49 lpetit: because he has to remember / dig clojure/contrib for examples, ...

10:50 rhickey : I'll try to draw a more comprehensive answer to your question tonight, when time permits to analyse all the cases (if it's not too late)

10:50 rhickey: there is also an underlying 'truth' that can't be papered over in an attempt to make things simpler, e.g. methods are not first class

10:52 djork: maybe there should be either a #clojuredev or #learnclojure channel :P

10:52 My vote would be #learnclojure

10:52 ambient: that probably wouldn't work very well

10:52 lpetit: rhickey: out of the top of my head: is the problem related to the fact that protocols and interfaces can be mixed ?

10:53 octe: djork: yes, i ind rhickey's discussions interesting and don't want to disrupt them

10:53 find*

10:53 with my newbie questions

10:54 djork: I mean there should be experts in both, but our noob ramblings just don't seem to fit sometimes :D

10:54 ambient: djork: i think it's easier just when people hang around without actively participating in the teaching process. when somebody poses a question, it's easier to just give the answer if there is time/patience. it requires separate effort to log and stay into the teaching channel. and i don't think it is any bother to ask questions in this channel. IMHO FWIW

10:54 octe: djork: yes

10:55 djork: that's true

10:55 rhickey: lpetit: not really, I'm happy to set aside interface considerations. relevant just to protocols are: a) deftype and reify methods are methods, not functions, and this *is* a special (non-)argument to methods, and b) the 'this' argument will rarely be used

10:55 djork: might as well not fragment the community where it's not absolutely necessary

10:57 chouser: octe: don't worry about interrupting with newbie questions. They might get scrolled off and forgotten when other conversations are heppening, but nobody will be annoyed or bothered.

10:57 ambient: if one is a total newbie in clojure, one should read a book and the excellent tutorial by R. Mark Volkmann

10:57 tmountain: does anybody know if there have been any efforts to create any fun clojure tutorials akin to "casting spels in lisp"? http://www.lisperati.com/casting.html

10:57 lpetit: djork: and the frequency of some newbie questions is part of questioning rich & others concerning the current state of the doc, the ease of use of some features, the frequency of usage of some features etc.

10:57 chouser: octe: on the other hand, I'm afraid a newbie channel might be mostly full of newbies misleading each other. :-/

10:57 djork: yeah

10:57 octe: yes..

10:58 djork: hmm, yeah, if 10 people ask the same question one day, it might be a signal

10:58 ambient: heh, newbies misleading other newbies. it happens more often than not

10:58 chouser: nothing gets a response faster in here than an incorrect answer.

10:58 octe: after running shutdown-agents, is it possible to resurrect them?

10:59 djork: tmountain: that looks like fun... I think I have seen it before

10:59 chouser: the clever newbie might leverage that by logging in under a different nick and giving himself bad answers to provoke responses.

10:59 octe: chouser: yes, another proven strategy for getting help.. ask the questions in a trolling way :)

10:59 rhickey: chouser: yikes!

10:59 chouser: rhickey: :-)

10:59 tmountain: djork: a few others in the same spirit, http://learnyouahaskell.com/ and http://learnyousomeerlang.com/

11:00 ambient: yeah, why bother when plain old trolling works just fine :P

11:00 octe: http://www.bash.org/?152037 feels relevant

11:00 djork: hah, yes octe

11:00 did you see the "kissed a girl" thing from Sun?

11:00 chouser: foo: is into lazy? not-foo: yes, just like all other binding mappers.

11:00 octe: djork: yes

11:00 funny

11:01 ambient: although i suppose people here are too pragmatic to be so easily trolled

11:01 octe: http://paste.lisp.org/display/91353 <- is this a good/bad way to do it?

11:02 chouser: yeah, pure trolling mostly gets ignored, thank goodness.

11:02 KarlThePagan: ambient: just start a message passing benchmark argument?

11:02 like our functions, trolling is higher-order

11:02 ambient: but then one would not be a newbie :/

11:02 octe: KarlThePagan: was that supposed to be directed to me?

11:03 djork: octe: It's just a sense I get but I feel like there's too much going on

11:03 octe: djork: yeah..

11:03 djork: octe: you've got refs, agents, and future

11:03 * ambient thinks he just reached his meta-discussion quota for the day

11:03 KarlThePagan: octe: no, i was giving an example of how to troll a functional language chan ;)

11:03 octe: ah

11:03 djork: oh wait, they're not refs, you're just calling agents refs because they are derefs

11:04 octe: djork: yeah

11:04 fliebel: Hmmm, I think those Head First guys should do a book on Clojure…

11:04 djork: deref'able... whatever the term is

11:04 octe: i could name it sum-agents, but it can sum anything that needs to be deref'ed :)

11:04 djork: I think Wrox should do a book on Clojure

11:04 octe: i think someone should recruit _why

11:04 * djork is kidding...

11:04 fliebel: Who is Wrox?

11:05 ambient: djork: heh, good one

11:05 djork: Wrox is the worst tech publisher ever... "for programmers by programmers"

11:05 no thanks

11:06 fogus: djork: Do they publish those big red books?

11:06 djork: they usually put a picture of the author on the cover which always reinforces the fact that it was written by a "regular programmer"

11:06 octe: djork: beards?

11:07 fliebel: How good is the Clojure book listed on Clojure.org?

11:07 octe: after doing a google image search for wrox books i see very little beards

11:07 djork: (I'm exaggerating)

11:07 ambient: fliebel: stuart's book? it's pretty good imo

11:08 * ambient uses aphostrophe completely random

11:08 * tmountain suffered through a class using a Wrox book as the core text in college

11:08 fliebel: ambient: Maybe I'll get that someday… Although nothing beets Head First imo.

11:08 ambient: it's easier to extract information from the book than the hive brain of internet

11:09 octe: hmm, rich doesn't seem to have one either.. have i been fooled? i thought you needed one to be an expert

11:09 micampe: fliebel: I have it, it's good if you are new to lispy/functional languages

11:09 fliebel: ambient: For Python and PHP I found the web a very good teacher and reference. I learned Java from Head First, but did PHP and Python without any books.

11:10 ambient: fliebel: clojure requires a bit more effort to grok. both python and php are very traditional

11:10 in a sense that they're somewhat derived from algol

11:10 djork: I think Clojure's docs are a good study in docs that are very helpful if you start at the beginning and read to the end.

11:10 octe: ambient: yes, languages like those generally just require you to learn the stdlib

11:10 fliebel: But my impressions with Clojure so far is that the web is not so useful and most language concepts new, which makes them hard to learn on my own.

11:11 ambient: fliebel: reading through core.clj is also a learning experience

11:11 djork: starting with "The Reader" feels funny

11:11 but it's also very good

11:11 fliebel: That is what I mean… they are all more or less C-like...

11:11 djork: but coming from curly-braces languages you get this feeling like "OK, cut to the chase..."

11:11 thehcdreamer: I would like to learn some java to take advantage of clojure java compatibility. Anyone know of a book or reference I can read online to get started? I need to reach a level where I can understand java syntax and being able to call libraries from clojure.

11:12 djork: thehcdreamer: there's really nothing to Java

11:12 fliebel: thecdreamer: I'm not sure for online, but for a real book I'd finitely recommend Head First Java :D

11:13 ambient: thinking in java by bruce eckel was free iirc

11:13 thehcdreamer: djork: I find it confusing to browse java documentation for libraries I may need in clojure, like Date

11:13 fliebel: djork: what did you mean with that quoted sentence? "OK, cut to the chase..."

11:14 thehcdreamer: fliebel, ambient thanks

11:14 angerman: clojures agents makes me want to have many cores... two are ok, but so little

11:14 fliebel: thecddreamer: Head First Java has some character dedicated to understanding the library.

11:14 angerman: and more memory

11:15 djork: fliebel: I mean that it's just an impulse coming from languages where syntax patterns are ingrained, and you just want to know how to translate your previous experience into a new syntax

11:15 you have internalized things like "code is split into lines"

11:16 and you want to jump into the library of functions

11:16 ambient: functional programmin is not a trivial step to process

11:16 djork: no

11:16 fliebel: I see...

11:16 djork: so with Clojure's docs you get a bigger picture by starting with the reader, etc.

11:16 introducing the repl as a fundamental part of the language

11:17 whereas with other languages it's like "OK you know how source code works... here's how to make an array"

11:17 ambient: in clojure you dont tell the computer how to do stuff, you tell it what to do

11:17 djork: right

11:17 fliebel: ambient: that is quite confusing....

11:18 djork: well, I dunno

11:18 FP is more declarative than imperative

11:18 so I'd say it's the opposite

11:18 octe: does doseq do recur?

11:18 djork: no

11:19 fliebel: declarative: "denoting high-level programming languages that can be used to solve problems without requiring the programmer to specify an exact procedure to be followed."

11:19 djork: you can of course have other forms inside of doseq that serve as a recur point

11:19 fliebel: well never mind then :P

11:19 octe: djork: when i add (doseq [agent agents] (println agent)) to a catch-expression i get "Cannot recur from catch/finally"

11:20 djork: oh I see what you mean

11:20 can you paste?

11:21 chouser: octe: yeah, doseq uses recur internally

11:21 chouser: ah, ok

11:21 how would i do that then?

11:21 chouser: octe: and you can't (currently) use recur in a catch block.

11:21 djork: doseq does use recur and it is a macro

11:21 octe: yes, that's what i suspected

11:21 djork: that's kind of an odd gotcha

11:21 chouser: just put the body of your catch block in a separate function, and call it from the catch

11:22 you can even do that all in-line if you want.

11:22 octe: i find it kind of odd that you get a regular java.lang.Exception when an agent has errors and you try to deref it

11:22 would be nicer if it was a specific exception

11:22 chouser: octe: agent error handling is being redone.

11:22 fliebel: I am developing the habit to run macroexpand-1 on everything I encounter now...

11:22 octe: i can't check for errors before i deref it since they may happen between the cehck and deref, right?

11:22 djork: man, doseq is one hairy macro

11:22 chouser: djork: not as bad as 'for' :-P

11:23 octe: but that's a ways off. :-/

11:23 djork: for looks like it is broken up into three main pieces

11:23 octe: chouser: nice, i

11:23 djork: doseq just kind of goes on

11:24 fliebel: ,(macroexpand-1 '(doseq [a [1 2 3]] (println a)))

11:24 clojurebot: (clojure.core/loop [seq_8240 (clojure.core/seq [1 2 3]) chunk_8241 nil count_8242 (clojure.core/int 0) i_8243 (clojure.core/int 0)] (if (clojure.core/< i_8243 count_8242) (clojure.core/let [a (.nth chunk_8241 i_8243)] (do (println a)) (recur seq_8240 chunk_8241 count_8242 (clojure.core/unchecked-inc i_8243))) (clojure.core/when-let [seq_8240 (clojure.core/seq seq_8240)] (if (clojure.core/chunked-seq? seq_8240) (clojure.co

11:24 djork: HOLY GOD

11:24 I just did exactly the same thing in my repl

11:25 [1 2 3] and all

11:25 :P

11:25 it is bigger than clojurebot wants to print

11:25 fliebel: strange, in repl it's quite small...

11:25 chouser: fliebel: might depend on your version of Clojure

11:26 djork: clojurebot might be running a different version

11:26 ,*clojure-version*

11:26 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}

11:26 chouser: chunked seq support requires quite a bit more code

11:27 fliebel: mine is: {:major 1, :minor 0, :incremental 0, :qualifier ""}

11:27 djork: there you go

11:27 you must have grabbed the jar from clojure.org

11:27 fliebel: what is chunked seq support?

11:27 Indeed...

11:28 Well, at least MacPorts did.

11:28 chouser: chunked seq support (with docs!) is coming for 1.1.0

11:29 fliebel: chouser: I figured that, but what does that mean?

11:29 Or is it half a wiki to explain?

11:30 chouser: there's a video. some slides.

11:30 ambient: i think it has something to do with granularity

11:30 djork: fliebel: I would clone from github

11:31 chouser: one line summary is they allow you to use exactly the same high-level functions you do today, but they run faster (with a bit less laziness).

11:31 djork: chunked seqs break up the computation of seqs into bigger pieces so that lazy seqs don't have to kick off a generation function for every element

11:32 fliebel: cool, so it's just optimization I wont notice?

11:32 chouser: fliebel: you can take some advantage of it without noticing, yes.

11:34 fliebel: I have done nothing productive or remotely useful with Clojure yet, but I'm starting to like it. I just did my first concurrent line of code without even noticing!

11:35 ambient: im doing progressively larger projects

11:35 fm synth > genetic image construction > jpeg

11:35 rhickey: anything else we wanted deprecated in 1.1? add-classpath, ^, parallel.clj

11:36 * ambient is a bit miffed that priority queues are so awkward to code for some reason

11:36 fliebel: Lol, commas are whitespace aren't they? I just noticed that Clojure preserves them when printing the representation of a map.

11:36 chouser: fliebel: yeah, inserts them.

11:37 ,{1 2 3 4 5 6 7 8}

11:37 clojurebot: {1 2, 3 4, 5 6, 7 8}

11:37 fliebel: cool

11:37 djork: the printer is nice to us

11:37 fliebel: ,[1 2, 3 4,,,, 5 6]

11:37 clojurebot: [1 2 3 4 5 6]

11:38 fliebel: Indeed :)

11:39 chouser: rhickey: I guess not for 1.1. Do you have any interest in discussions (now or post-1.1) about character literals or escape sequences in strings?

11:40 rhickey: chouser: you mean the interpolation stuff?

11:40 fliebel: How far of is 1.1?

11:40 chouser: rhickey: no, I just mean \newline and/or "\n"

11:40 rhickey: chouser: what about them?

11:41 djork: I like character literals

11:42 rhickey: chouser: you can just point me to the discussion if I missed it

11:42 chouser: no, there's been no discussion. except in my head. :-P

11:42 rhickey: ah, there

11:43 fliebel: Can someone explain me the use of \newline?

11:43 ,(str \newline "\n")

11:43 clojurebot: "\n\n"

11:44 micampe: should I use Java APIs to send data over a socket or is there something useful in clojure?

11:44 chouser: ,(map class [\newline "\n"])

11:44 clojurebot: (java.lang.Character java.lang.String)

11:45 fliebel: chouser: memory efficiency?

11:45 noidi: is there a function for transforming (a1 b1 c1 a2 b2 c2 a3 b3 c3 ...) to ((a1 a2 a3 ...) (b1 b2 b3 ...) (c1 c2 c3 ...)) ?

11:45 micampe: oh, I found examples, great

11:46 chouser: fliebel: no, just a way of naming a character in clojure source code. C uses '\n' vs "\n" for char vs string. Clojure uses \newline

11:46 fliebel: ah, that is why \n returns just n...

11:47 replaca_: are we deprecating ^ ?

11:47 chouser: right. \n looks exactly like a newline, but isn't.

11:47 replaca_: yes, use (meta ...) instead.

11:47 fliebel: Fun ingredients for some code obfuscation :D

11:47 replaca_: chouser: how come?

11:48 djork: \n looks like a newline *in other languages*

11:48 replaca_: do folks want it for something else?

11:48 chouser: djork: \n is newline in clojure strings.

11:48 djork: yes

11:48 ,(apply map vector (partition 3 (range 12)))

11:48 clojurebot: ([0 3 6 9] [1 4 7 10] [2 5 8 11])

11:48 chouser: replaca_: yes, type hints. (defn add [x^Integer y^Integer] ...)

11:48 rhickey: replaca_: yes, would like ^ to replace #^

11:49 maybe what chouser said too

11:49 the latter could happen without deprecation

11:50 I mean x^String could happen just by making ^ ok inside symbols

11:50 chouser: well, x^{:tag String, :foo :bar} would be nice too

11:50 replaca_: rhickey, chouser: I see. Priorities. Need that old APL keyboard so we don't have to make choices :-)

11:50 rhickey: but #^ seems to really trip people up, brings out the perl remarks

11:51 replaca_: I use ^ all over the place (mostly in the autodoc stuff), but I'm not really *that* hung up on it

11:51 chouser: quote behavior is less surprising with trailing ^

11:51 rhickey: chouser: still don't need to deprecate for that

11:51 fliebel: what is #^? I can't google that characters.

11:52 rhickey: I think the existing metadata would be cleaned up a lot with ^ vs #^

11:52 replaca_: fliebel: substitute for with-meta at read-time

11:52 chouser: rhickey: you mean without reordering it?

11:52 Chousuke: ,(meta #^{:foo 'bar} [])

11:52 clojurebot: {:foo bar}

11:52 rhickey: replaca_: No

11:52 replaca_: I agree ^ is a lot prettier

11:52 fliebel: another macro...

11:52 replaca_: oops, no?

11:53 rhickey: #^ != with-meta

11:54 clojurebot: (clojure.core/meta x)

11:54 clojurebot: x

11:54 rhickey: ,(meta (read-string "#^String x"))

11:54 clojurebot: {:tag String}

11:54 chouser: with-meta attaches metadata to an object at runtime

11:55 replaca_: right, that's what I meant. It's like with-meta, but at read time

11:55 fliebel: ok, thanks

11:56 replaca_: but I get what you mean, it's not a straight macro expansion

11:56 rhickey: replaca_: people think that #^ and ^ are analogues

11:57 replaca_: rhickey: Yeah, #^ is a problem for the pretty printer cause you can't read code with it and then prety print it back out and get what you expect.

11:57 rhickey: so describing the behavior of #^ given that presumption is tricky

11:57 replaca_: that's why to do real code reformatting, we'll need a custom reader

11:58 rhickey: replaca_: you can't? even with *print-meta* ?

11:58 replaca_: (that treats both #^ and ; specially)

11:58 yeah, you can print the meta data on something, but it wasn't necessarily applied with the form you just read

11:59 (although I don't yet support *print-meta* in the pretty printer and I should)

11:59 rhickey: replaca_: do you have an example?, I'm confused

11:59 clojurebot: "([s]); Reads one object from the string s"

12:00 replaca_: rhickey: hang on a sec and I'll cons one up

12:00 lisppaste8: rhickey pasted "explicit elided this" at http://paste.lisp.org/display/91364

12:01 rhickey: so, in thinking about implicit this, trying to tease out the 2 aspects - the elision from the arglist, and the implicit name

12:01 the latter is a no go for reify

12:01 chouser: because of nesting

12:02 replaca_: ,(binding [*print-meta* true] (print '(def f #^{:a 7} 'bar)))

12:02 clojurebot: DENIED

12:02 rhickey: the above paste proposes unified syntax for deftype/reify/extend-*, where this arg is always eilided, but never implicit

12:02 if you want to refer to this, must supply this-name where indicated, same name applies throughout

12:02 chouser: optionally implicit?

12:03 rhickey: chouser: no, never implicit

12:03 always elided

12:03 replaca_: rhickey: I don't know why the bot doesn't like that, but that produces "(def f (quote bar))"

12:04 chouser: replaca_: it just doesn't like the word 'def'

12:05 replaca_: chouser: picky, picky

12:05 chouser: ,(binding [*print-meta* true] (print '(f #^{:a 7} 'bar)))

12:05 clojurebot: (f (quote bar))

12:05 chouser: ,(binding [*print-meta* true] (prn '(f #^{:a 7} 'bar)))

12:05 clojurebot: (f #^{:a 7} (quote bar))

12:07 rhickey: replaca_: is the metadata even there?

12:07 (-> '(fred f #^{:a 7} 'bar) (nth 2) meta)

12:07 ,(-> '(fred f #^{:a 7} 'bar) (nth 2) meta)

12:07 clojurebot: {:a 7}

12:07 replaca_: rhickey: no, I munged the syntax

12:07 Chousuke: rhickey: that syntax looks pretty good.

12:08 replaca_: rhickey: but check this out: "(binding [*print-meta* true] (prn '(def f #^{:a 7} 'bar)))"

12:08 clojurebot can't do it, but (when f is deffed in my repl), I get:

12:09 #^{:line 1} (def f #^{:line 1, :a 7} (quote bar))

12:09 lpetit: rhickey: concerning implicit this and methods / functions, I'd say if possible, have implicit this for methods, and then have methods defined with the leading dot, and have explicit this otherwise (and not leading dot for the function)

12:10 replaca_: which is not what I typed in

12:10 lpetit: replaca_: Would a rewrite of pprint be worth the trouble, as far as possible performance gains are involved ?

12:10 rhickey: replaca_: because of the line stuff?

12:11 lpetit: replaca_: I meant, a rewrite using protocols

12:11 replaca_: Chousuke: and there are a bunch of other reasons that an object can have metadata besides that

12:11 rhickey: lpetit: leading dot for protocol method defs too?

12:11 lpetit: rhickey: yes, "a cat is a cat", sort of

12:12 chouser: a shame the this-name has to be in a vector, but it's good that its consistent.

12:12 lpetit: rhickey: and implicit this comes with methods (OO hat), explicit "this" comes with functions (functional hat)

12:12 rhickey: lpetit: ick, dot is so host-y, I;d hate to have it be part of describing pure protocols + deftype

12:12 replaca_: since pprint hacks things up before printing them, the metadata on any object is relevant and since you can't tell if it came from the form you're printing or not

12:12 chouser: ,(binding [*print-meta* true] (prn (read-string "(def f #^{:a 7} 'bar)")))

12:12 clojurebot: (def f #^{:a 7} (quote bar))

12:12 replaca_: you cant really use the *print-meta* mechanism

12:12 magnet: (OT: "appeler un chat un chat" translates to "to call a spade a spade")

12:13 chouser: replaca_: the metadata really is on those objects. to not print it would be a lie.

12:13 replaca_: you can use read-string as I showed there, or some other mechanism, to get objects that don't have line numbers and such attached.

12:14 replaca_: chouser: that's true, if your goal is to do what *print-meta* is trying to do, but not if you're trying to print the expression as read

12:14 chouser: no, that's how it *is* read. that metadata is there as soon as the thing is read

12:14 replaca_: chouser: I think there's potentially more stuff than just line numbers

12:14 chouser: it may not be what you typed, but it's what was read.

12:15 lpetit: rhickey: is the fact that protocol method defs are methods an implementation detail or not ? Even if so, is this implementation detail a "leaky abstraction" in terms of what one can or cannot do (closures or not, pure functions or not) ... If yes, then maybe let the abstraction leak in an explicit way ?

12:15 chouser: similar to how ; comments work. you typed it, but the reader doesn't produce anything for it

12:15 replaca_: yes, but an object can have other metadata on it. I haven't thought about this in a long time. I'll have to put together some more precise examples

12:16 chouser: hm, maybe you're wanting to print source code with type hints but not other metadata?

12:16 rhickey: lpetit: well, there will have to be some discussion of implicit access to the fields and the non-first-class-nature of 'methods', but not really a tie to Java and interop like dot might imply - for instance, you won't be calling the protocol methods via .method

12:17 replaca_: chouser: If I'm trying to reformat source code, I want to be able to reconstruct only those things the user entered

12:17 lpetit: rhickey: not be calling them via .method -> sounds right, since the (possible, maybe I'm wrong ?) "leaky abstraction" is more on the def side , isn't it ?

12:17 chouser: huh. maybe should be :clojure.core/line

12:18 replaca_: rhickey: yeah, but in the context of the pretty printer, it's possible for arbitrary user metadata to be attached to something (e.g. a symbol) when I'm trying to print it, I think

12:18 rhickey: I'll have to reconstruct my original logic on this and make sure I'm right. I thought about it pretty hard back in February or so :-)

12:19 rhickey: replaca_: but why wouldn't you print it if *print-meta* was true? Either it's what they read or they mucked with it

12:19 hiredman: I imagine the prettyprinter is a whole 'nother kettle of fish

12:19 chouser: rhickey: with the "explicit elided this", recur always matches the arg count of the literal arg vector?

12:19 rhickey: chouser: no

12:19 replaca_: rhickey: right, *print-meta* was your suggestion :)

12:19 rhickey: I was just talking about using the pretty printer to do code reformatting

12:20 lpetit: I haven't yet thought much about using protocols in the pretty printer

12:21 rhickey: lpetit: I don't understand your last comment

12:21 chouser: I think recur behavior, while telling, is low priority

12:21 chouser: ok

12:21 replaca_: lpetit: The one problem that comes up is tht the pretty printer is based on extended java writers which are classes and not interfaces :-(

12:21 lpetit: rhickey: I agreed that from the calling side, not calling via .method seemed ok to me

12:22 replaca_: :-(

12:22 rhickey: lpetit: it's necessary, since some implementations of protocols will not be methods at all, i.e. protocols are not interfaces

12:23 * rhickey is always amazed by the design differences between java.io and java.util

12:23 rhickey: jekyll and hyde

12:24 chouser: something about (extend-class String [s] ...) where s is implicit first arg seems neat

12:24 and in the frequent case where you don't use this, you just leave it out

12:28 lpetit: my first cut with deftpe/reify implementing protocols had .method and implicit this - .method bothered me the most, a mismatch with protocols

12:30 lpetit: rhickey: I must leave, but I'll re read the fundamentals of what we're talking about first, in the wiki, and then will come back to this discussion concerning the syntax (if I have ideas, of course :-) )

12:31 rhickey: lpetit: ok, thanks

12:32 seems like splitting off implicit from eliding isn't helping anyone

12:39 lisppaste8: rhickey annotated #91364 "vs explicit supplied" at http://paste.lisp.org/display/91364#1

12:41 rhickey annotated #91364 "most extends will supply this" at http://paste.lisp.org/display/91364#2

13:00 chouser: rhickey: I don't think I understand your first example there yet

13:01 is [this-name] there, or not? if supplied, you don't include it in each method?

13:06 Chousuke: if it can be omitted, it just reduces to the confusing case in most siutations

13:06 situations*

13:14 srader: rhickey: I think I found a bug in deftype

13:14 rhickey: chouser: [this-name] is only needed if you want to refer to this in any method body, never impacts arglists

13:14 srader: (deftype Foo [a b c]) (def foo (Foo 1 2 3)) (:a foo)

13:15 chouser: rhickey: ah, that's what you mean by not-implicit. If not specified, there's no way to refer to it?

13:15 srader: eval that twice and I get #<Foo$__lookup__a user.Foo$__lookup__a@128594c>

13:16 rhickey: chouser: right

13:16 srader: ok, will check that out

13:25 rhickey: srader: fixed -thanks for the report

13:30 esj: is there a function of a map that returns a struct-map of that map ?

13:32 i could map over the map assoc'ing into the struct-map, but that seems a bit roundabout ?

13:33 rhickey: esj: why do you want the struct-map?

13:33 esj: to share the keys between all the struct-maps efficiently.

13:34 rhickey: esj: so the map is a prototype for many more?

13:34 esj: exactly.

13:35 i will get many instances of the map over time, and I want to store them.

13:37 cark: esj: there is create-struct as a starting point for your function

13:37 rhickey: ,(let [m {:a 1 :b 2 :c 3} s (apply create-struct (keys m))] (apply struct s (vals m)))

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

13:38 esj: great stuff, thanks.

13:39 i'd come up with this: (reduce (fn [c [a b]] (assoc c a b)) (struct-map struct-reading) reading) is it obviously worse ?

13:39 where 'reading' is the map in question

15:00 rongenre: ,clojurebot (< Double/MIN_VALUE 0)

15:00 clojurebot: java.lang.Exception: Unable to resolve symbol: clojurebot in this context

15:00 rongenre: ,(< Double/MIN_VALUE 0)

15:00 clojurebot: false

15:00 rongenre: Yeah, that's not right

15:01 Chousuke: hmmh

15:01 rongenre: I'm assuming it's kind of a silent overflow

15:01 Hun: ,Double/MIN_VALUE

15:01 clojurebot: 4.9E-324

15:01 Hun: in my book that's still > 0

15:02 that would be least-positive-double-float

15:02 rongenre: yup.

15:03 rongenre: Oh good. MIN_VALUE for double means.. smallest positive

15:03 great

15:05 liebke: _ato: are you around? Clojars is throwing a sql exception when I try to add someone to the incanter group. Have you seen this before?

15:07 kotarak: Is it possible to define a print-method for things implementing a Protocol?

15:10 stuartsierra: ,(Double/MIN_VALUE)

15:10 clojurebot: 4.9E-324

15:10 stuartsierra: ,(Double/MAX_VALUE)

15:10 clojurebot: 1.7976931348623157E308

15:10 rhickey: kotarak: hopefully printing will be based upon protocols at some point

15:11 kotarak: rhickey: yes, that's my pain at the moment. I want to print a modified IMapEntry as [k v], but it is not recognised as such.

15:12 Since I use reify, I cannot define a custom print-method. But with deftype, it should be possible in the AOT case, no?

15:13 rhickey: a protocol isn't a type, so type based dispatch won't cover all participants in a protocol

15:13 but deftype will give you a deterministic result from (type x), AOT or not

15:14 kotarak: argh. Right. So I should probably go with deftype and the protocol.

15:14 rhickey: so current printing can be extended with deftype, not protocols

15:15 technomancy: liebke: _ato is on australian time; probably asleep right now.

15:16 kotarak: Hmm.. How is printing a IMapEntry handled anyway? I extend IMapEntry so shouldn't it print like a "normal" IMapEntry?

15:16 Chousuke: rhickey: hm. did redefining a protocol reset it completely? (even if the protocol doesn't change) If not, I guess that would nearly solve the print-method problem that causes trouble if you try to re-eval all of clojure.core during runtime.

15:16 neatly* :P

15:16 liebke: technomancy: you never know when a hacker is awake :)

15:17 alexyk: how do you guys parse the command-line options?

15:17 technomancy: true =)

15:18 alexyk: ?

15:18 kotarak: alexyk: there is c.c.command-line

15:19 alexyk: ok... and what's the way to declare the "main"?""

15:20 The-Kennz: alexyk: (defn -main [] ...)?

15:20 kotarak: alexyk: http://clojure.org/Compilation

15:20 The-Kennz: alexyk: http://clojure.org/compilation

15:20 heh.. kotarak was faster

15:20 alexyk: thanks! the URL are case-insensitive, I guess

15:21 is defn- main same as defn -main?

15:21 Chousuke: no

15:21 kotarak: defn- is a private defn

15:21 alexyk: what's -main then?

15:21 Chousuke: alexyk: the - in -main is a naming convention used when defining java methods.

15:22 you need gen-class in order to have a "main" in Clojure.

15:23 kotarak: alexyk: you can add any prefix you like: (gen-class ... :prefix MyCoolPrefix-) (defn MyCoolPrefix-main ...) Nice when defining multiple classes in one namespace.

15:23 chouser: in order to have a Java main that is

15:23 alexyk: Chousuke: ok... do you have to define a main in order to run from the command line? Or can I run with clojure <some opts> <myfiles>?

15:24 I'm usually running things after maven makes a jar out of them, since mvn ...run doesn't distinguish stderr and stdout

15:27 kotarak: with deftype I can still override Object methods, like toString, right?

15:33 jasapp: is there something similar to common lisp's :print-function for clojure structures?

15:36 michaeljaaka: hi

15:37 is there any easier way to do that? http://gist.github.com/246622 note that filter-neg is an func defined by user

15:37 kotarak: rhickey: hmm.. extenders do not contain eg. (deftype Foo [] [Protocol] ..), is this correct?

15:42 Chousuke: michaeljaaka: (filter identity (map f seq))?

15:42 hm, I guess not.

15:43 michaeljaaka: hmm output the same

15:43 is it lazy?

15:44 Chousuke: yes

15:44 it maps f over a seq and removes anything nontrue

15:44 ie. nils and falses

15:44 chouser: kotarak: yes

15:44 michaeljaaka: Chousuke: so it is the same

15:45 i exactly wanted to get that effect

15:45 Chousuke: michaeljaaka: right. I just misread your function a bit :

15:45 kotarak: chouser: hmm.. And what is the reason, why Foo should not be in extenders? Is it to retrieve "after-design-time" extensions?

15:46 Chousuke: michaeljaaka: there are remarkably few things you can't do with the standard seq functions. :P

15:46 chouser: kotarak: sorry, was answering your first question: deftype can overrice toString

15:46 kotarak: chouser: ah. Ok. Found that out already. :)

15:46 michaeljaaka: Chousuke: so FP is just for me ;)

15:47 Chousuke: every time you start constructing an explicit lazy seq you should stop and ponder if you could just find the right combination of map, filter and partition for it :P

15:47 michaeljaaka: Chousuke: well identity was the key

15:48 chouser: kotarak: I don't think I understand your second question.

15:49 rhickey: kotarak: me either

15:50 kotarak: chouser: I did (deftype LazyMapEntry [k v] [ILazyMapEntry IMapEntry] ...). My code failed because IMapEntry and IPersistentVector are in extenders (added by extend-protocol) but ::LazyMapEntry was not. Hence extends? returned nil. Then I found out, that I really wanted satisfies?. That works also for the deftype. But let me check again.

15:50 user=> (extenders ILazyMapEntry)

15:50 (clojure.lang.IMapEntry clojure.lang.IPersistentVector)

15:51 * chouser watches his mental model fall apart. Again.

15:52 rhickey: kotarak: extenders returns only the classes/type for which extend* was called

15:52 as you discovered, satisfies? is the test

15:53 kotarak: rhickey: ookk? Is there a special reason? I mean I could do (deftype Foo [] [Protocol] ....) and then (extend ::Foo Protocol some-mixin-map)

15:54 rhickey: kotarak: special reason for what? it answers a specific question. The set of types specifying a protocol is never going to be listed in extenders

15:54 since it is an open set

15:54 all derivees of an interface that extends a protocol for instance

15:55 they won;t all register

15:55 kotarak: hmm... then I don't get the use of extends?.

15:55 rhickey: also, there may be at some point a way to ask for the method map of an extender - there isn't one for a deftype that implements directly

15:55 kotarak: ah. ok.

15:56 rhickey: there are many ways to participate in a protocol, explicit extends is just one

15:56 extenders/extends? is just about explicit extenders

15:56 kotarak: rhickey: then (deftype .... (foo [] ..)) is not the same as (deftype ...) (extend ... {:foo ...})?

15:57 rhickey: kotarak: not at all

15:57 kotarak: ok

15:57 rhickey: in the former case the type participates in the protocol by implementing its interface

15:58 and the implementations are methods of the class

15:58 in the latter case it is an explicit registration of a map of ordinary fns

15:58 chouser: but users of the deftype don't need to know which, as long as it 'satisfies?'?

15:59 kotarak: so the former is faster, I guess..... No mixins for deftype, then?

15:59 No, of course not. deftype method are not closures.

15:59 rhickey: kotarak: I've been thinking about that, might be possible - method calls fn

16:00 just working on that today

16:00 kind of a mismatch with the macro aspect of deftype

16:02 there will be a way to ask a protocol for the implementation of a fn for a specific extender

16:02 right now:

16:02 user=> (-> P :impls ::Bar :foo)

16:02 #<user$eval__135$fn__140 user$eval__135$fn__140@68302e67>

16:02 get impl of foo for type Bar

16:03 that can't be supported by non-extenders

16:03 chouser: because a deftype method is a java method, and therefore not a thing of its own.

16:03 rhickey: right

16:04 michaeljaaka: Chousuke: I often use (defn map-apply[f col] (map #(apply f %) col)) is there any fun to give the same effect?

16:04 rhickey: and not registered, part of the open set of implementors of the protocol interface

16:05 chouser: michaeljaaka: your col is nested seqs? [[1 2 3] [4 5 6] [7 8 9]] ?

16:05 michaeljaaka: yes

16:06 chouser: ,(apply map list [[1 2 3][4 5 6][7 8 9]])

16:06 clojurebot: ((1 4 7) (2 5 8) (3 6 9))

16:06 chouser: hm, that's the wrong axis

16:07 michaeljaaka: I can't think of any better way to do that.

16:07 michaeljaaka: ok

16:07 thx

16:11 chouser: rhickey: deftype doesn't adjust the protocol object or functions at all does it.

16:12 each protocol fn starts with a case for handling objects that implement the protocols matching interface, and thats how a deftype hooks in?

16:12 rhickey: chouser: nope

16:12 oops, 2 questions

16:12 chouser: yep, sorry.

16:13 rhickey: right, deftype implementing a protocol doesn't alter it

16:13 there are a few layers to the implementation

16:13 each function of the protocol has a fast-path preamble that checks for an instance of the protocol interface, and makes a method call as you saw

16:14 chouser: ok

16:14 rhickey: that will be the case whenever a protocol fn is used as a first-class object

16:14 but callsites now know about protocols

16:14 chouser: ah

16:14 whoa

16:15 rhickey: whenyou compile a function that calls foo, where foo is a protocol fn, the compiler will look at the protocol, find the interface, find the method, and burn in that fastpath preamble right into your function

16:15 chouser: callsites see that the symbol being called is a protocol fn and not some other local or var, in order to do special things?

16:15 whoa

16:15 ok

16:15 rhickey: yep

16:16 and hotspot will inline those calls

16:16 just like you said .foo

16:16 chouser: but with so much more flexibility

16:16 rhickey: right, so much more

16:16 chouser: and no type hints

16:17 rhickey: and ease of use, vs (defn bar [#^IProtocol x] (foo x))

16:17 heh

16:17 kotarak: rhickey: to take karmazilla's words "dude, you are made of awesome :)"

16:17 chouser: haha

16:18 rhickey: plus the call sites do additional caching for the non-interface case - they will look up the callee in the extenders map, find the method, and store it right in the caller

16:18 so no lookup as long as same target type

16:19 so calls to extenders (like if you extended String) are also very fast at sites where the target is homogenous

16:19 chouser: probably about as fast as a direct fn call

16:19 rhickey: right

16:20 chouser: hm. to a local fn, not through a var

16:20 rhickey: no, through a var since it needs to see dynamic updates

16:20 chouser: oh, ok.

16:21 rhickey: but the check happens i nthe pipeline - since it has the fn to call cached, the fastpath proceeds to set that call up while the pipeline pulls the var and tests against local for identity

16:21 it is definitely faster than waiting to see what's in the var and using that

16:21 so, say, in between direct and through var

16:21 chouser: huh. cool.

16:22 you're referring to the CPU instruction pipeline here?

16:22 rhickey: right

16:22 the guard does need to pull the var, and the test is for no change, but the fastpath presume true for that, and has the value already in hand

16:23 chouser: kotarak: it's entirely possible that quote is backwards, and that awesome is made of rhickey.

16:23 rhickey: vs, you know nothing, have to wait for the var result to proceed

16:23 chouser: rhickey: yep, I think I've got it.

16:23 kotarak: HAHA!

16:24 rhickey: the coolest thing is that non of this speed requires AOT

16:24 nene

16:24 none

16:24 * rhickey can't type

16:25 leafw_: rhickey: drunk with happiness

16:25 kotarak: awesomeness ;)

16:26 technomancy: chouser: time for a clojure-specific spin-off of http://www.schneierfacts.com/ it sounds like

16:26 chouser: I once promised a blog about Clojure warts. But the list is small and likely to shrink as work gets done, so I'll just paste it. typos and all

16:26 rhickey: so, if you know in advance and have control, putting the protocol impl right in deftype/reify is as fast as interface call, but of you don't, no worries, it's still very fast (only the tiniest methods will be dominated by dispatch overhead), and the flexibility is still there

16:26 lisppaste8: Chouser pasted "warts" at http://paste.lisp.org/display/91391

16:27 leafw_: chouser: triple quotes would be great, python-like. I find myself with problems on the docs of fn with lits of \"

16:27 s/lits/lots

16:28 and use/require is being worked on, IIRC

16:28 chouser: leafw_: I don't know if I'd advocate triple quotes, but having no way at all to avoid \" is a pain

16:28 Chousuke: that error messages are frequently completely useless is the biggest wart I can think of.

16:29 but hopefully that will change as things develop

16:29 chouser: Chousuke: but that's the implementation, not the language itself.

16:29 Chousuke: I guess so.

16:29 leafw_: Chousuke: I find error messages ok, one I filter out all the non-clj lines.

16:30 except, perhaps, for macros.

16:30 s/one/once

16:30 chouser: Chousuke: I mean, that issue doesn't mess make my source files look worse than if it were fixed.

16:30 s/mess//

16:33 StartsWithK: (macroexpand (.toString Integer 1)) expands to (. (clojure.core/identity Integer) toString 1) in 1.1a, shoudn't that be just (. Integer toString 1)?

16:33 rhickey: chouser: the newline stuff is very funny

16:35 chouser: ,(macroexpand-1 '(Integer/toString 1))

16:35 clojurebot: (. Integer toString 1)

16:35 chouser: StartsWithK: so, no.

16:35 StartsWithK: ,(macroexpan '(.toString Integer 1))

16:35 clojurebot: java.lang.Exception: Unable to resolve symbol: macroexpan in this context

16:35 StartsWithK: ,(macroexpand '(.toString Integer 1))

16:35 clojurebot: (. (clojure.core/identity Integer) toString 1)

16:35 chouser: rhickey: what's funny, clojure or what I said?

16:36 StartsWithK: If you want a static method of Integer, use Integer/toString. If you want an instance method, use (.method object args)

16:37 StartsWithK: chouser: i know that, i was just wondering why in that form there is a extra identity call

16:37 chouser: StartsWithK: saying (.toString Integer 1) is trying to call an instance method named "toString" on an instance of Class

16:38 once upon a time, we had FAQ #1, and we called identity ourselves.

16:38 StartsWithK: oh i see, that is not a valid call

16:38 rhickey: chouser: both

16:39 chouser: rhickey: is most of that inherited from CL or something?

16:39 rhickey: not really, but if you think about the alternatives... you'd need to reserve \ for excaping and use something else for chars?

16:41 chouser: I guess '\n' is out. ;-)

16:41 Java has no syntax for Character literals?

16:41 rhickey: right, single quote is taken. CL used #\ for chars, doesn't really change things

16:42 chouser: oh, Java uses '\n' like C. hmph.

16:42 using the same lookup table as strings would allow \n to be a newline for some better consistency, but I guess that would make space be just

16:43 space be just \ which is annoying

16:43 ...though that works today, just prints as \space

16:43 rhickey: what would be 'n' ?

16:44 * chouser is stumped.

16:44 chouser: I spent more time thinking up the problem than any solutions.

16:44 rhickey: you have to eat another special char, or #combo

16:45 chouser: #\newline = \n = (first "\n") ?

16:48 lpetit: \ca \cb ... for direct ASCII/UTF8 encoding, \uFFFF for unicode code, \xFF for US-ASCII codes ?

16:49 And then \n is not reserved anymore, nor \t ... and all the usual conventions inherited from C

16:49 rhickey: chouser: what is 'n' ?

16:50 chouser: Maybe #\n

16:50 lpetit: but I don't like it very much, having to add c .. How many times do you use lots of literal characters, though ?

16:50 The problem remains that you have \n inside strings, and .... something else for chars

16:50 chouser: right, "\n" is not to be messed with

16:51 so to make things any more consistent, \n would have to mean (first "\n")

16:51 which, as rhickey keeps pointing out, leaves the question of (first "n")

16:52 notallama: what about \\n = (first "\n") ?

16:53 lpetit: (first "n") could be \cn

16:53 chouser: since "\156" = "n", \156 should definitly be (first "n"), but that hardly seems sufficient.

16:53 lpetit: (first "a") could be \ca

16:53 notallama: nevermind. \\n woiuld make it rather hard to do a literal \

16:53 chouser: notallama: \\\ :-)

16:54 notallama: chouser: i'm getting bad memories of java regex

16:55 java regex literal \ is "\\\\"

16:55 chouser: I think I like #\n over \cn

16:56 notallama: yep. We fixed that in Clojure a while ago. :-)

16:56 technomancy: notallama: you should see Emacs regexes

16:56 terrifying

16:56 notallama: yes, i'm aware, and i greatly appreciate it

16:58 lpetit: chouser: but then, if #\n stands for (first "n"), what would be (first "\n") N

16:58 chouser: \n

16:58 rhickey: ouch

16:58 notallama: i'm not really a fan of breaking \x = (first "x"). it'd be nice to keep that, at least for everything except one escape character.

16:59 lpetit: less consistent than \cn \n

16:59 rhickey: lpetit: putting c before things trashes scanability IMO

16:59 lpetit: (but still, I don't like \cn very much, just sticking to something that may be a standard in regular expressions, as I found in the above mentioned link)

16:59 rhickey: scanability ?

17:00 chouser: it's a problem for all string escapes, which include \n, \t, \r, etc.

17:00 rhickey: anytime you put dummy (but alpha) characters before important characters you make you brain do extra work to remove them

17:00 * lpetit searches the definition of scanability

17:01 rhickey: i.e. how easy is it to tell if they are in alphabetical order?

17:01 * rhickey made up scanability

17:01 lpetit: We're talking about character literals. How often are they "heavily" used in practice ?

17:02 rhickey: lpetit: not often, I don't consider the problems chouser has raised as problems at all, for me personally

17:03 lpetit: rhickey: maybe not, but interestingly I had the exact same bug recently. Wrote \n where I should have written \newline :)

17:03 chouser: ah, yes. \a \b \r \f \n \t and \v, plus the fancier ones for hex or octal

17:04 liebke: it doesn't seem like a problem... once you consider the alternative solutions :)

17:04 lpetit: liebke: so sometimes it helps consider alternatives :

17:04 :)

17:04 liebke: indeed :)

17:05 chouser: ,\o156

17:05 clojurebot: \n

17:05 chouser: ,\o12

17:05 clojurebot: \newline

17:05 chouser: "\o12"

17:05 ,"\o12"

17:05 clojurebot: Unsupported escape character: \o

17:06 chouser: this doesn't just seem broken to you?

17:06 lpetit: ,"\o12"

17:06 clojurebot: Unsupported escape character: \o

17:06 chouser: ,(str \o12)

17:06 clojurebot: "\n"

17:07 lpetit: ,"\u12"

17:07 clojurebot: Invalid character length: 2, should be: 4

17:07 lpetit: ,"\u0012"

17:07 clojurebot: ""

17:07 lpetit: ,"\u0032"

17:07 clojurebot: "2"

17:07 chouser: ,\u0012

17:07 clojurebot: \

17:07 notallama: does java do octals in strings?

17:07 chouser: ,\u0032

17:07 clojurebot: \2

17:07 chouser: notallama: yes

17:08 lpetit: ok I don't have the ascii table wired in my head :)

17:08 chouser: notallama: no

17:09 notallama: yes. sorry. :-)

17:09 notallama: \ followed by digits is octal, even without a leading 0

17:11 so again in Clojure we have \12 and "\o12" are invalid, but \o12 and "\12" are valid and mean almost the same

17:12 Clojure string literals are very similar to Java string literals. Maybe identical. Clojure character literals feel like they're from an entirely unrelated language.

17:15 lpetit: ,"\c"

17:15 clojurebot: Unsupported escape character: \c

17:15 notallama: \\n makes the most sense to me. java version would be '\n'. so basically, \x would be the same as 'x'

17:17 lpetit: Or just make the escaping rules be written the same inside strings and for chars, and for ease of use of writing literal chars, add an additional character. Rich said that using an alpha character is not interesting since it creates mental noise (downgrades scanability), so maybe a different char

17:17 \_a , \_b , ...?

17:17 hiredman: I would be ignored if clojure's handling of character literals changed in a backwards incompatible manner

17:17 for the record

17:17 er

17:17 lpetit: maybe too close to _

17:17 hiredman: s/ignored/annoyed/

17:18 chouser: hiredman: you prefer how it is now?

17:18 lpetit: \'a, \'b ?

17:18 \'a' \'b' ?

17:19 Chousuke: noisy

17:19 chouser: lpetit: and for newline, \'\n or \'\n' ?

17:19 lpetit: for newline \n

17:19 hiredman: chouser: I like to be able to revisit old code without have to spend a lot of time to make it work

17:19 and I don't mind it as it is now

17:20 lpetit: \'<one char of your charset>' , and any other escape mechanism similar to what is done in strings for the rest : \n , \t , \b , \u9882 ...

17:21 chouser: lpetit: I like that. Even better without the trailing '

17:21 lpetit: or just 'a' for chars, like in java ?

17:21 isn't it possible, even if ' is for quoting ?

17:21 chouser: we already see ' as a prefix thing in Clojure code, so \'n isn't too bad for the unusual bare letter case

17:21 hiredman: chouser: none of the proposals seen here are nice enough to entice me to want to break working code

17:22 lpetit: \newline could be kept as a deprecated (or more readable) non-shortcut for \n

17:22 chouser: ,(str 'n' "hello")

17:22 clojurebot: "nhello"

17:23 hiredman: chouser: cute

17:23 lpetit: but yes, \n , \t, \b would break

17:23 hiredman: I don't see how \'n is in anyway an improvement

17:24 chouser: it's just to free up \n to mean the same as (first "\n")

17:24 lpetit: and also \b, \t, and make them behave the same as in "\n" "\b", etc.

17:24 chouser: right

17:25 rhickey: what's ''' ?

17:25 '\''

17:25 lpetit: ?

17:25 chouser: \''

17:25 rhickey: \'\''

17:26 lpetit: \''

17:26 \'"

17:26 LauJensen: Man this is great, just like the J forum :)

17:26 lpetit: and \'\ for (first "\\")

17:26 \'a' could be accepted as a convenience, also :

17:26 :)

17:27 :-(

17:27 sorry

17:28 ,\"

17:28 clojurebot: \"

17:28 chouser: \" and \'" would both be accepted and mean the same

17:29 lpetit: yes

17:29 chouser: if we used something new instead of \ then old code could remain compatible

17:29 lpetit: but isn't this a particularity of a particular host platform (the JDK)

17:30 or a particularity of the dominant language of the host platform ?

17:30 chouser: #\n for newline, #\'n for n

17:30 hiredman: :|

17:30 chouser: or #'n for n

17:31 hiredman: uh

17:31 ,#'n

17:31 clojurebot: java.lang.Exception: Unable to resolve var: n in this context

17:31 chouser: oh

17:31 hiredman:

17:31 chouser: maybe not. :-)

17:31 lpetit: chouser: rather staying with the current implementation, or breaking existing code, than adding patches and not removing old behaviour

17:32 chouser: old behaviour could be deprecated but left in place until hiredman comes around in his thinking.

17:32 hiredman: lpetit: so reader macros by patch?

17:32 lpetit: I have so bad experiences with the Eclipse API, adding new ways of doing the same thing over old ones, forcing you to "replay" all the history to understand things

17:33 hiredman: didn't understand

17:33 hiredman: you could, just, you know, leave the character handling as is

17:33 lpetit: one argument against reader macros is it essential shatters the language into sublanguages with different syntaxs

17:33 chouser: sure. could also leave any number of other broken things broken.

17:33 lpetit: Yes, I guess better leave it as is, than adding another way to do it, and leaving the old way.

17:34 hiredman: chouser: is it really broken?

17:34 lpetit: Or, have the courage to break broken things, but this example may not be worth it.

17:34 chouser: ,\o12

17:34 clojurebot: \newline

17:34 chouser: ,"\o12"

17:34 clojurebot: Unsupported escape character: \o

17:34 chouser: broken.

17:34 lpetit: ,"\12"

17:34 clojurebot: "\n"

17:35 chouser: ,(= \n (first "\n"))

17:35 clojurebot: false

17:36 lpetit: hiredman: I'm not sure it's the current main arguments. The same can be said about regular macros. I remember the main argument for Rich was along the lines that it's difficult to keep them "in scope" (but I'm no expert)

17:36 * twbray notices that the character geeks are here, so...

17:36 notallama: maybe \\ as the escape sequence. that way, \x works as is (even when x = \), and you get to type more characters to type your characters!

17:36 twbray: What's the syntax for an arbitrary Unicode character, e.g. U+4F5B ?

17:36 notallama: so \\\n = (first "\n")

17:37 lpetit: in strings "\u4F5B"

17:37 ,"\u4F5B"

17:37 clojurebot: "佛"

17:37 chouser: also in literals. yay!

17:37 ,\u4F5B

17:37 twbray: lpetit: Thanks

17:37 clojurebot: \佛

17:37 chouser: not broken!

17:37 lpetit: not broken :)

17:37 too late for me :)

17:37 chouser: :-)

17:37 twbray: chouser: so if you have unicode, screw the rest, make 'em all use that :)

17:37 chouser: there ya go

17:37 lpetit: ok, so from now on, everybody is writing literals in unicode esac

17:38 shit you beat me again :) :)

17:38 chouser: ,"this\u000Ais\u000Anice!"

17:38 clojurebot: "this\nis\nnice!"

17:39 hiredman: chouser: \o is not a valid escape, so the reader throws an exception, how is that broken?

17:39 lpetit: ,(printf "this\u000Ais\u000Anice!")

17:39 clojurebot: this is nice!

17:39 chouser: hiredman: \o is valid esacpe outside "" but not inside

17:39 hiredman: no

17:39 chouser: hiredman: \u is valid in both

17:39 hiredman: outisde of "" it is not an escape

17:39 chouser: ,\o12

17:39 clojurebot: \newline

17:40 chouser: \12 is valid inside "" but not outside

17:40 twbray: ,"foo\uabar"

17:40 clojurebot: Invalid digit: r

17:40 chouser: \n is valid in both, but means different things.

17:40 lpetit: is \u valid in non-java strings (e.g. C#, ...) ?

17:40 twbray: "foo\u000abar"

17:41 ,"foo\u000abar"

17:41 clojurebot: "foo\nbar"

17:41 chouser: lpetit: Clojure mimics Java string literals, but doesn't borrow the implementation, I believe. So Clojure strings literals will mean the same across host platforms.

17:41 twbray: ,"foo\00000abar"

17:41 clojurebot: "foo

17:42 lpetit: chouser: are you sure ?

17:43 twbray: OK, I think there's a bug there. Unicode characters go up to U+10FFFF

17:43 oops typo

17:43 ,"foo\u00000abar"

17:43 clojurebot: "foo

17:43 chouser: lpetit: pretty sure. LispReader.java has Clojure's rules for reading string and char literals.

17:43 twbray: ,"foo\u10346bar"

17:43 clojurebot: "fooဴ6bar"

17:44 lpetit: chouser: good, so the change would be meaningful for every clojure port

17:44 twbray: Oh crap those \u thingies are recognizing UTF-16 codepoints not unicode characters. Per Java's big mistake

17:45 twbray: OK... U+10346 is GOTHIC LETTER FAIHU

17:45 you probably don't have a font for it.

17:46 chouser: does that take two UTF-16 words to describe or something?

17:46 twbray: So you'd have to encode this is "foo\ud800\udf46bar"

17:46 * chouser is clearly an insufficient char geek.

17:46 chouser: ah, ok.

17:46 twbray: ,"foo\ud800\udf46bar"

17:46 clojurebot: "foo𐍆bar"

17:46 rlb: chouser: http://java.sun.com/developer/technicalArticles/Intl/Supplementary/ (I think)

17:46 Java can't fit all unicode characters into a char.

17:47 twbray: They're called "surrogates". You don't want to know if you don't have to.

17:47 rlb: (just codepoints)

17:47 Some unicode characters in utf-16 won't fit in 16-bits.

17:47 twbray: You could make a case that Clojure should Do The Right Thing and recognize \u10346

17:47 rlb: (but java pretended they would -- or just didn't care)

17:48 (or the standard changed -- don't know offhand)

17:48 twbray: rib: When Java was being cooked up, people still believed in UCS2, i.e. that you would be able to fit everything in 16 bits.

17:48 hiredman: you would then need a seperate \u for char literals

17:48 Chousuke: twbray: the reader works with java's Characters :/

17:48 twbray: hiredman: Maybe \U

17:48 rhickey: \ae, \bee, \cee, \dee , \ee , \ef , \gee, \newline, \tab ... \zee

17:48 hiredman: the reader works with ints

17:48 rlb: twbray: oh, ok, I thought it might also have been historical.

17:49 hiredman: because .read returns an int

17:49 rhickey: phonetic character literals!

17:49 Chousuke: hiredman: well they're cast to chars :P

17:49 basically.

17:50 hiredman: sure

17:50 twbray: There are lots of good things about being on the Java platform, but Unicode isn't one of them. Life would be so much easier if it were UTF-8 end to end.

17:50 Chousuke: well, UTF-8 is just an encoding for unicode.

17:51 twbray: Chousuke: Agreed. But one that has many advantages over what Java happened to pick.

17:51 hiredman: but if you, for example, write a reader in clojure which turns int into Integer and char into Character, and then there is not auto back and forth between the two …

17:51 chouser: rhickey: perfect!

17:51 rhickey: obviously I have nothing constructive to add :)

17:51 lpetit: \one \two ...:)

17:52 Chousuke: twbray: yeah. I suppose processing UTF-8 is a bit more complicated than UTF-16, but since most character data is ASCII or UTF-8, that advantage suddenly becomes a disadvantage :P

17:52 * bitbckt checks on his petition to use Hangul for all written language

17:52 rlb: Chousuke: processing utf-16 is basically as hard if you do it right (i.e. neither is a fixed encoding.)

17:53 s/fixed/fixed-width/

17:53 twbray: I wrote a nice UTF-8 based java.lang.String replacement which uses UTF-8 internally. But it's too late.

17:53 lpetit: But was it UTF16 or raw UCS16, really ? :-)

17:53 twbray: rib: +1

17:53 hiredman: bitbckt: :(

17:53 twbray: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF if anyone cares

17:54 rlb: It's just that the characters with more than one utf-16 code point are not as common.

17:54 bitbckt: hiredman: You'll get used to it. :-)

17:54 hiredman: hangul has too many variations of the o and yo sound that all sound the same to me

17:54 bitbckt: I refuse

17:54 rlb: (at least in many arenas)

17:55 Chousuke: is hangul capable of expressing all the sounds in the English language?

17:55 the latin alphabet certainly isn't. :P

17:55 hangul has no f

17:55 koreans shout "powl" at basketball games

17:56 bitbckt: And we all *laugh*

17:56 hiredman: pheonix becomes peenix

17:57 it is very noticable because of the amount of english that gets phonetically written in hangul

17:57 Chousuke: I wonder if that makes it worse than katakana

17:58 bitbckt: The generations of people taught English from books, without actually ever *hearing* a native English speaker are also a source of great amusement.

17:58 hiredman: yes

17:58 Chousuke: I had to listen to a person keep a presentation in English class today. She had horrible pronunciation.

17:59 Pronunciation is clearly not given enough attention in schools.

18:00 bitbckt: See? The Roman alphabet isn't phonetic. Fail. ;-)

18:00 Chousuke: You basically learn it if you already have some sort of natural aptitude for it, but if you don't... Well, sucks to be you. Or actually, sucks to be anyone who hears you speak English :P

18:00 Well, the problem is that the Finnish alphabet is almost phonetic.

18:00 hiredman: accents are nice

18:00 Chousuke: So many Finns just learn to pronounce English like it was finnish

18:00 which is *completely* and *utterly* hideous

18:01 hiredman: I don't know exactly what the problem is in korea, but kids go through years of english classes at school plus after school english study, and still can only string together a few words

18:02 Chousuke: I remember seeing pictures of a teacher's book in Japanese that just had all the english parts transliterated as katakana

18:02 so the teacher had no need to actually know how to read English

18:02 hiredman: my dad is an english teacher there, so he, at times, will go on and on on the subject, and the deficiencies of *other* english teachers

18:02 twbray: hiredman: we have the same problem in English-speaking countries. Kids study French or whatever for years and can't speak at all.

18:02 hiredman: twbray: I suppose

18:02 but it seems much less common

18:03 Chousuke: I at least had an English teacher in high school with a proper British accent :)

18:03 hiredman: all the kids I know who studied japanese speak it

18:03 bitbckt: Chousuke: I suppose that's an "improvement."

18:03 lpetit: So that means everybody agrees on the switch to \'a :-)

18:04 Chousuke: at least you could hear the proper intonation in her speech

18:04 hiredman: nope

18:04 Chousuke: the pronunciation guides in books don't really teach that :/

18:04 and since Finnish has next to no intonation, that leads to most people speaking quite monotonously, even if their pronunciation is otherwise good.

18:05 hiredman: my dad was once accosted by another english teacher, and accused, in a thick cockney accent, of teaching koreas a horrible american accent

18:06 Chousuke: lpetit: I think that looks hideous, but... :P

18:06 bitbckt: hiredman: I'm sure that was an amusing conversation.

18:06 lpetit: was a joke

18:07 stand1: General question: Does anyone know of an effort underway to get decent date/time functions into clojure. My searches don't turn up anything.

18:07 bitbckt: stand1: Use joda?

18:07 lpetit: ~jodatimes

18:07 clojurebot: I don't understand.

18:08 clojurebot: First, out of 6580 results is:

18:08 Joda Time - Java date and time API - Home

18:08 stand1: Is that java or clojure?

18:08 the-kenny: stand1: Java

18:08 But you can always write a simple wrapper :)

18:08 hiredman: (what's the difference)

18:08 lpetit: ~google jodatimes clojure wrapper

18:08 clojurebot: First, out of 82 results is:

18:08 gcv&#39;s cupboard at master - GitHub

18:09 stand1: I'm actually interested in doing a wrapper.

18:09 lpetit: ok sorry

18:10 rhickey: from the protocols wiki page = what does it mean to "implement a protocol on an interface" ? How does it look in practice ?

18:11 stand1: how common is it to wrap a third party jar like joda. I was thinking of implementing on top of the jdk to avoid dependencies.

18:11 hiredman: why wrap?

18:12 stand1: mainly to avoid lots of heavy lifting.

18:12 hiredman: is there a lot of heavy lifting you need to do?

18:12 stand1: date arithmatic, formatting, etc.

18:12 time zones

18:12 hiredman: I am unfamiliar with joda time, but it should do all that

18:13 bitbckt: It slices! It dices!

18:13 Call now and we'll *double* your order!

18:13 stand1: it make julian calendars!

18:14 It's quite complete. I'm not sure there's much anyone needs from a time library that isn't in Joda.

18:16 hiredman: drives me crazy when "quick start" java guides don't mention what package any of the classes are in

18:16 stand1: botbckt: Don't disagree, but I'm thinking of more clojure and less java. i.e. wrappingn

18:16 hiredman: sorry!

18:16 bitbckt: botbckt is my bot. :-)

18:17 stand1: So, using Joda directly via Clojure's Java integration is not what you want..?

18:18 stand1: well, for example a now function that returns a date structure {:month :day :year etc}

18:18 A (format-date format-string date) function. things like that

18:18 hiredman: ,(bean (Date.))

18:18 clojurebot: {:seconds 18, :date 1, :class java.util.Date, :minutes 20, :hours 15, :year 109, :timezoneOffset 480, :month 11, :day 2, :time 1259709618423}

18:19 bitbckt: I think the consensus opinion has been the Joda doesn't really need anything like that.

18:19 stand1: hiredman: that's close

18:19 bitbckt: that*

18:20 alexyk: is clojure all lazy, as in lazy evaluation like in Haskell, or are just seq's lazy?

18:20 hiredman: just lazy-seqs

18:21 alexyk: ah.

18:21 hiredman: java interop would be *extremely difficult and painful* if it was lazy evaluation

18:29 stand1: Wow! Matt Moriarty has done something quite close to what I was thinking http://gist.github.com/49656 I found on a thread on the mail list.

18:41 hiredman: alexyk: for and doseq are the most "foreach" like constructs

18:41 for is actually a lazy list comprehension

18:41 (not a loop)

18:41 alexyk: ok!

18:41 hiredman: doseq is very foreachie

18:42 ,(doseq [i (range 3)] (print i))

18:42 clojurebot: 012

18:53 djork: oh neat, I didn't know I could do a \uXXXX literal

18:54 and I was doing "\u000d" when apparently \return exists

18:56 is there some list of these somewhere?

18:56 Chousuke: hmm

18:57 djork: ,(map char (range 1 33))

18:57 clojurebot: (\ \ \ \ \ \ \backspace \tab \newline \ \formfeed \return \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \space)

18:57 djork: looks like all the basics

18:57 good enough for most console work

18:58 djork: woo! hiredman with the scoop!

18:58 but that's CIC, not in use yet, right?

18:58 hiredman: dunno if my reader ever will be

18:59 djork: impressive nonetheless

19:00 hiredman: anyway, it was a more or less one to one transliteration of the java, so those literals there should be reliable at least for another few days (till Chouser changes everything)

19:03 Chousuke: I have a reader too. haven't worked on it for a while though

19:03 no time :(

19:03 hiredman: me neither (lazy :)

19:16 rhickey: lpetit: (extend-class AnInterface AProtocol (foo [x ]...))

19:16 lpetit: rhickey: yes, I've understood it in the mean time

19:19 rhickey: here are my current thoughts concerning "this", problems with recur consistency, etc. : http://paste.lisp.org/display/91400

19:20 rhickey: I also have a couple of questions that may be interesting to be answered in the wiki ?

19:20 rhickey : a) In deftype, does the redefinition of hasCode/equal work as an atomic thing (redefine neither or both), or not ?

19:21 rhickey : b) In deftype, why doesn't IPersistentMap interface have default implementation such as IObj and ILookup ?

19:22 rhickey: c) What is the reason for using keywordized versions of type name and protocol methods name over symbols in extend ?

19:22 twbray: Eleven theses on Clojure: http://www.tbray.org/ongoing/When/200x/2009/12/01/Clojure-Theses

19:23 djork: "1. It’s the Best Lisp Ever · I don’t see how his can be a controversial statement."

19:23 well duh

19:23 (typo, BTW)

19:23 rhickey: lpetit: if you define hashCode or equals, both u pto you, no enforcement you define both

19:24 twbray: djork: Thanks, fixed

19:25 rhickey: lpetit: b) IPersistentMap include ILookup, IObj always

19:25 lpetit: rhickey: d) (and the last one) Would adding extend-interface (even if under the hood it shares everything with extend-class) be interesting to manifest that we're just implementing an interface over a protocol ?

19:25 rhickey: lpetit: c) symbols are a pain in not self-quoting

19:25 lpetit: rhickey: hashCode/equals = ok, maybe wiki could state this more explicitly ?

19:25 rhickey: d) interfaces are classes

19:26 lpetit: rhickey: d) Yes, but conceptually different

19:26 djork: twbray: Do you think that infix math is maybe the only thing really tripping people up when it comes to Lisp syntax?

19:27 if you change the operators to English words it gets a little easier to read, I think

19:27 Logo was a Lisp and we did that in 3rd grade

19:27 twbray: Start in 3rd grade and the problem goes away :)

19:27 djork: heh

19:27 I guess so

19:28 rhickey: twbray: thanks for spending some time with Clojure and covering is so well!

19:28 covering it

19:28 lpetit: rhickey: b) was not clearly expressed. I wanted to ask : " why is there no default implementation for IPersistentMap in deftype. Why having to explicitly add the interface to trigger the default implementation" ?

19:29 twbray: rhickey: If it weren't for the sucky bytes->string mapping, Clojure would have slam-dunked the wide finder field in terms of the ratio between the lines of code and resulting performance.

19:29 (Java's mapping, not clojure's)

19:29 rhickey: lpetit: I'm still on the fence about these default implementations. deftype is a very general purpose thing, not just for structmap replacement. You should be able to use it to implement PersistentHashMap itself

19:29 djork: nice writeup though, twbray

19:30 twbray: are you sure you used the best methods to read bytes into Java strings?

19:30 there are various ways

19:30 twbray: djork: Nope. But it's a problem that I'm fairly familiar with.

19:30 djork: k

19:31 rhickey: lpetit: so, I really don't want people to treat non-collections as collections, but some of the current interfaces are trapped in hierarchies, that, when protocols, will be more a la carte

19:31 twbray: Going from UTF-8 to UTF-16 is always going to suck

19:31 lpetit: rhickey: but why a special case for PersistentHashMap over ILookup and IObj ? Why not the same "treatment" as for hashCode and equals : if not present, default implementation, if one of the methods present, user implementation ? No special cae

19:31 case

19:32 bitbckt: twbray: As always, I enjoy your coverage of these things... and photography.

19:32 Thanks.

19:32 rlb: I need to partition a seq of vectors based on a predicate that depends on the previous element. I can write a function that produces a suitable lazy seq, but I wondered if that's the most reasonable way.

19:32 lpetit: rhickey: oh, ok for IPersistentHashMap, then

19:33 rhickey: lpetit: because IPersistentMap carries a lot of semantics people won't necessarily understand nor want. Keyword field lookup and metadata are relatively atomic and primitive

19:33 lpetit: rhickey: What about my lisppaste ? There's really nothing new, but gives my opinionated opinion on the subject, after having grokked the concepts again from the wiki pages :)

19:34 rhickey: lpetit: I don't like dots anywhere near protocol fns - they just scream 'host interop'

19:34 djork: so, twbray, you are at Sun? do you know what Sun-in-general thinks about Clojure?

19:35 twbray: djork: Sun currently in process of being acquired, no opinions are to be expressed.

19:37 lpetit: rhickey: oh, for me, they were there to say "not a function". But I understand the case for 'host interop' screaming. It would indeed be indented in italic for such a purpose in ccw, for example. And that would be bad.

19:37 cubix: is there a nicer way to do this or a function that already exists somewhere? http://paste.lisp.org/+1YIY

19:37 rhickey: lpetit: the more I stare at explicit this: http://paste.lisp.org/display/91364#1 the less it bothers me

19:38 lpetit: rhickey: so there's just the recur consistency problem left ?

19:38 rhickey: lpetit: with that, yes, the least likely to be encountered

19:41 lpetit: rhickey: why do you say so ?

19:42 rhickey: lpetit: less likely to be encountered than inconsistencies between deftype/reify/extend etc, not unlikely or never

19:43 lpetit: ,(doc reify)

19:43 clojurebot: excusez-moi

19:43 rhickey: every possible solution has some inconsistencies

19:44 lpetit: rhickey: what does it mean to place type hints on the explicit "this" in method arg list :-p

19:45 rhickey: lpetit: nothing

19:46 lpetit: rhickey: it's amusing, we walked the same road in the opposite direction, you arriving where I started from (and vice versa), and we're happy with our final destination :)

19:46 rhickey: lpetit: because we are walking in circles? :)

19:47 lpetit: rhickey: I mean, now that I have really read the last versions of protocols and types wiki pages, I'm not annoyed by your solution of having no "this" at all by default, and declaring an explicit this outside of any methode arglist if necessary. And it would make the recur case consistent. And it would somehow remind that those are not real fns

19:48 (deftype AType [AProtocol AnInterface] :as explicit-this (aProtocol-method [] ...))

19:49 rhickey: spirals, not circles :)

19:50 * dysinger is still hiring FT clojure devs - work at home - mbp 15" & 3g

19:57 rhickey: lpetit: recur would be inconsistent for extend-type then

19:58 lpetit: oh, you wanted explicit this in extend-type

19:58 lpetit: rhickey: yes

19:58 rhickey: then extend-type and deftype are inconsistent (in an understandable way perhaps)

20:00 lpetit: rhickey: yes, after having reasonably grokked the differences between extend-type and deftype, it makes sense for them to be inconsistent concerning "this" handling (at least it does for me)

20:00 rhickey: as a practical matter, extend type will need to use 'this much more often

20:01 but the question will be asked - why make us state 'this in every method when you have this nicer solution for deftype/reify

20:02 lpetit: rhickey: by "reasonably", I mean if one understands why its preferable for performance to inline the implems in deftype (if one owns deftype definition), one understands that deftype does not define real functions. And is happy with implicit this in deftype, and explicit this in extend-*

20:03 rhickey: lpetit: but now I am having a conversation with someone on this side of the understanding hill

20:03 lpetit: rhickey: and the answer could be "because a cat is a cat, and you don't have the same performance characteristics" ?

20:04 rhickey: but a macro is a macro (extend-type) and could have taken away this tedium

20:05 lpetit: rhickey: sure, so the inconsistency of recur could also be got rid of by the macro, maybe ?

20:05 (ok, certainly *not easy if at all possible*)

20:07 I must leave, see you later !

20:07 rhickey: lpetit: bye - thanks for the input!

20:07 lpetit: my pleasure

20:22 arohner: rhickey: do you have a reaction to http://groups.google.com/group/clojure-dev/browse_thread/thread/ad5597c4eb89ce40/6125b18ef9542df5?show_docid=6125b18ef9542df5 ? Is the lack of deftype introspection a real problem, or am I doing it wrong? 2) what do you think a good solution to this problem is?

20:23 defn: How do you use (accessor)?

20:24 rhickey: I think something like this will be built in - no need to add on later

20:26 arohner: rhickey: ok, thanks. Are there any workarounds until that happens?

20:29 rhickey: arohner: if you take IPersistentMap default implementation, you will have (keys x), and IDynamicType has getExtensionMap, keys without the keys of the extension map == the fields

20:31 arohner: sigh. at one point when I was trying to make deftype implement a protocol to work, I took out my IPersistentMap declaration, then forgot to put it back in. if (keys x) had worked for me, I never would have set off down this path.

20:31 thanks

20:32 well, the good news is I understand the deftype implementation a lot better!

20:35 is it possible to require that members of a protocol also implement an interface, say IPersistentMap?

20:36 rhickey: arohner: no

20:36 the point of protocols is that such requirements can't be superimposed on all types

20:36 e.g. String

20:37 arohner: oh right. though after cinc, keys will be part of the Associative protocol, right?

20:37 rhickey: moving forward, it will be possible to write protocols that require other protocols, but only by convention, not enforcemed

20:38 yes, eventually all Clojure's key interfaces will be protocols

20:49 johannh: Hi all. Quick question: what's the right way to implement pmapcat? I want something like (pmapcat (fn [chunk] (map some-fun chunk)) (partition-all 1000 (line-seq rdr))), but I worry that (apply concat (pmap ...)) would force the entire sequence.

20:50 chouser: apply doesn't force seqs

20:51 johannh: So, apply is smart enough to bundle up the &rest argument into a lazy sequence?

20:52 I only ask because memory usage makes it look like the whole file is getting slurped in somewhere.

20:59 arohner: lisppaste8: url

20:59 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

21:02 arohner pasted "deftype extends explosions" at http://paste.lisp.org/display/91404

21:03 arohner: I can't get extend-class to work with existing classes or deftype

21:05 ah, extend-class expanded into (extend :winston.db-row/java.lang.Object

21:08 I've fixed the extend-class by removing the :: off java.lang.Object. now my protocol method works with normal classes, but not deftypes

21:08 is there a way to supply a default implementation for all deftypes?

21:11 notallama: do you need a different implementation for deftypes than Objects?

21:13 arohner: notallama: my one extend-class on java.lang.Object is happy with "normal" classes, and not happy with deftypes

21:13 so I assume so

21:15 I also assume that because extend-class and extend-type both exist, there must be some difference

21:20 notallama: the method for Object should work for everything that doesn't have its own implementation defined. that's not true for you? can you paste what you're doing?

21:21 except I removed the :: on extend-class

21:21 lisppaste8: arohner annotated #91404 "untitled" at http://paste.lisp.org/display/91404#1

21:24 notallama: you're implementing half an interface on object, and the other half in deftype. i'm pretty sure that doesn't work.

21:24 er, half a protocol

21:25 since you have the protocol in the deftype extend-list, it's trying to use that implementation, but you didn't define a method for insert

21:26 you could get the effect you want by splitting it into several protocols. (one for each method, or something)

21:27 arohner: notallama: ok thanks, I'll try that out

21:29 if that's the case, it really should be documented. it was not at all obvious that isn't allowed

21:30 notallama: arohner: i don't know if you're familiar with java interfaces, but it's pretty much the same idea: you either implement all the methods, or you don't use it.

21:31 hiredman: well, you don't brag about using it

21:31 arohner: I thought I was implementing all of the methods, just in two different places

21:32 still getting the same error

21:32 notallama: paste again?

21:33 lisppaste8: arohner annotated #91404 "untitled" at http://paste.lisp.org/display/91404#2

21:37 notallama: take inserttableRow out of the deftype, and it should work.

21:37 arohner: oh right, because I'm not providing a new method for that

21:37 yeah. it works

21:37 thanks.

21:47 rongenre: I'm using resultset-seq to unpack a jdbc resultset. Is there any way to get the struct which is used to make the records?

21:51 arohner: rongenre: not really. the struct is created dynamically during the resultset-seq call

21:52 ~def resultset-seq

21:52 see that line "row-struct (apply create-struct keys)"

21:53 rongenre: Yeah, i noticed there doesn't seem to be a def accessor on PersistentStructMap

21:54 Should I just rebuild the struct if I want to use accessors to access the fields? [I think there's a performance penalty otherwise]

21:55 arohner: that's one option

21:55 yes, accessors will be faster than normal map derefs

21:55 * map lookups

21:55 rongenre: Is there a better one?

21:56 I suppose I could hack a version of resultset-seq to return the new struct and the sequence

21:57 arohner: I was just about to suggest that

21:57 that's what I would do

21:58 rongenre: got it. Thanks.

22:36 churib: ,(doc recur)

22:36 clojurebot: It's greek to me.

22:36 churib: ,(+ 1 1)

22:36 clojurebot: 2

22:37 churib: ,(doc +)

22:37 clojurebot: "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0."

22:37 churib: ,(source +)

22:37 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

22:47 solussd: ,(println "does the bot talk?")

22:47 clojurebot: does the bot talk?

22:51 alexyk: somnium: in (fetch :collection {)

22:51 } )

22:52 (fetch :collection :only [:key]) -- is :only a keyword?

22:52 I recall it worked as a bare word, or I'm dreaming?

22:52 it's my mac brace-matching trinket

23:00 Drakeson: are there any good webkit bindings in java or clojure?

23:03 KarlThePagan2: Drakeson, there's a java.net project for rich browser integration - it's a subproject of JDIC (java desktop integration c????)

23:04 however it might only be internet explorer

23:04 so that may be no help to you

23:05 solussd: ,(.parseInt Integer "1")

23:05 clojurebot: java.lang.IllegalArgumentException: No matching method found: parseInt for class java.lang.Class

23:06 solussd: ,(. Integer (parseInt "1"))

23:06 clojurebot: 1

23:06 chouser: ,(Integer/parseInt "1")

23:06 clojurebot: 1

23:56 Drakeson: KarlThePagan2: thank. I am not really looking for a "browser" as per se. I want the lean renderer, mainly.

23:57 thanks

Logging service provided by n01se.net