#clojure log - Dec 12 2009

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

0:02 technomancy: back when I was all "HAY GUYSE HOW DO U PARSE A STRING?"

0:03 hiredman: hyperspec

0:03 hyperspec?

0:04 performance?

0:04 clojurebot: http://clojure.org/java_interop#toc46

0:07 hiredman: clojure?

0:07 clojurebot: clojure is cheating

0:08 tolstoy: Hey, that's what my manager, and his manager, and the architect said.

0:12 hiredman: clojurebot: twbray is <reply>you have to watch twbray, if you take your eye off him for a second he is likely to blog post

0:12 clojurebot: c'est bon!

0:12 twbray: hiredman: huh?

0:13 hiredman: twbray: just making sure clojurebot knows who you are

0:14 twbray: clojurebot: Pleased to meetcha

0:14 clojurebot: Pardon?

0:14 * twbray opens a blog-post buffer

0:34 alexyk: somnium: pingy-wingy

0:50 skybound_: is there anything like prxml that accepts an outputstream/writer? xml/emit seems cumbersome to use

0:55 alexyk: how do you get a seq from a Java iterator?

0:58 _ato: alexyk: call iterator-seq on it

0:58 alexyk: ok

1:00 hiredman: skybound_: emit prints to *out*, and you can bind *out* to whatever

1:02 alexyk: how do you sort a seq of tuples like (["a" 1] ["b" 2]) in descending order of the numbers?

1:02 hiredman: ,(doc sort-by)

1:02 clojurebot: "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

1:04 alexyk: hiredman: right, I forgot what java Comparator looks like :)

1:04 hiredman: forget the Comparator bit

1:04 ,(sort-by val '([a 2] [b 3]))

1:04 clojurebot: java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry

1:04 hiredman: grr

1:05 ,(sort-by second '([a 2] [b 3]))

1:05 clojurebot: ([a 2] [b 3])

1:05 skybound_: hiredman: right :-) thanks

1:06 alexyk: hiredman: almost there!

1:07 hiredman: !

1:07 npm: anybody know of any clojure packages or tricks that would help me find a ranked set of indexes within a sequence where a subsequence of values "best fits" within a larger sequence of values. (e.g. someone selects a set of features from a audio/video resource that i extract http://nielsmayer.com/prototype-11-17-2009.jpg .... and then i want to find that same selection in other sequences from other recordings that might not be exactly the same

1:07 )

1:07 * npm this is a bad group for forgetting to close parens :-)

1:08 alexyk: hiredman: so sort-by cannot do descending?

1:08 Carkh: ,(sort-by second > '([a 2] [b 3]))

1:08 clojurebot: ([b 3] [a 2])

1:08 alexyk: ,(sort #(> (%1 1) (%2 1)) '(["a" 1] ["a" 2])) ; this works too

1:09 Carkh: you need to read the doc with more attention !

1:09 clojurebot: (["a" 2] ["a" 1])

1:09 npm: ,(+ 1 1)

1:09 clojurebot: 2

1:09 npm: hm

1:09 cool

1:09 alexyk: Carkh: how does second > combine together?

1:09 Carkh: ,(doc sort-by)

1:09 clojurebot: "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

1:09 alexyk: ah right

1:09 Carkh: see the first line of the doc

1:09 alexyk: sorry I was distracted by java comparator from sort

1:09 npm: racks brain for which lisp "," syntax is from. CL?

1:09 Carkh: =)

1:09 hiredman: I guess I did tell him to ignore the comparator bit

1:10 Carkh: npm : clojurebot lisp, prety nice but you can't defn =(

1:10 alexyk: Carkh: yes, hiredman is to blame for everything good and bad :)

1:10 Carkh: alexyk : will do !

1:10 npm: hm, so if it's clojure,how can it prevent me from calling execute in java?

1:11 alexyk: :)

1:11 hiredman: clojurebot: whose job is it to recieve all blame?

1:11 clojurebot: that's KirinDave's job

1:11 hiredman: clojurebot: whose job is it to prevent npm from executing java?

1:11 npm: clojurebot how can you prevent me from creating infinite threads and DOSing you?

1:11 clojurebot:

1:12 hiredman: clojurebot: we demand answers!

1:12 clojurebot: Pardon?

1:12 hiredman: clojurebot: you heard me!

1:12 clojurebot: hiredman: I'm just giving you a second chance

1:12 hiredman: clojurebot: a wise guy, huh?

1:12 clojurebot: a is t

1:13 npm: clojurebot do you pass the turing test?

1:14 hiredman: clojurebot: what about the turing test?

1:14 clojurebot: what is wrong with you

1:14 hiredman: clojurebot: tell us about the turing test?

1:14 clojurebot: the answer is 42

1:15 _ato: hehe, just got real 12m0.027s / user 182m39.276s / sys 26m25.290s on twbray's widefinder 2 test, with shared clojure hashmaps inside atoms with atomiclongs as values. :-) that beats the java entry and I think I've still got a little room to improve

1:17 _mst had some great suggestions, which for some reason make the garbage collector pauses longer but it ends up being faster in the end anyway

1:17 * _mst is mysterious that way :P

1:17 hiredman: trashy suggestions

1:17 _mst: hahah yep

1:18 cp2: I failed the Touring test.

1:18 er

1:18 oops

1:18 :|

1:26 polypus: clojurebot: what are your passions?

1:26 clojurebot: what is wrong with you

1:42 alexyk: oh my god, running pagerank on twitter shows that justinbieber is #1 by mentions. I needed to look it up. Clojure brings me knowledge!

1:42 he & 1000 girls talking about him.

1:43 thank you, Clojure, I needed to program for decades to get to study Ashton Kutcher in detail with your help.

1:46 and Britney is only #50.

1:53 wavis: isa? is backwards...

1:54 can't use it with condp

2:23 qed: alexyk: haha, how are you doing that?

2:23 a library or something homemade?

2:23 alexyk: qed: clojure + jung2 :)

2:24 although clojure is a bit slow for pagerank, I'll use OpenMP and good ol' Fortran next

2:24 for that part

2:26 I mean even Java is slow for PageRank. Bow before C++, Java!

3:38 atif: ping

5:45 angerman: c++?

6:13 somnium: ~c++

6:13 clojurebot: Huh?

6:14 somnium: clojurebot: c++ |is| just what is a protected abstract virtual base pure virtual private destructor, and when was the last time you needed one?

6:15 ~c++

6:15 hmm

6:15 ,(+ 2 3)

6:16 clojurebot: No entiendo

6:16 5

6:18 somnium: clojurebot: c++ is <reply>just what is a protected abstract virtual base pure virtual private destructor, and when was the last time you needed one?

6:19 clojurebot: ping?

6:20 clojurebot: PONG!

8:31 * the-kenny thinks there isn't a single lisp-comic in xkcd Vol. 0 :(

9:50 interferon: are there any built-ins that let you check parameter types?

10:05 the-kenny: interferon: Sorry, I don't understand what you trying to do. Can you explain it?

10:05 interferon: i keep running into problems where i mean to pass an array of maps to a function and, through my own mistakes, i end up passing just the map directly in.

10:05 then i get cryptic NPE's

10:06 so for debugging purposes, i want osmething like CL's check-type

10:06 the-kenny: interferon: You can do type-hints on function arguments.

10:06 interferon: i can write it, but curious if it's built-in

10:06 type-hints don't check

10:06 rhickey: ,(cast String 42)

10:06 clojurebot: java.lang.ClassCastException

10:06 rhickey: like that?

10:07 the-kenny: You can also use (type ..)

10:08 rhickey: ,((fn [a b] {:pre [(integer? a) (integer? b)]} (+ a b)) 1 2)

10:08 clojurebot: 3

10:08 rhickey: ,((fn [a b] {:pre [(integer? a) (integer? b)]} (+ a b)) "1" 2)

10:08 clojurebot: java.lang.Exception: Assert failed: (integer? a)

10:08 rhickey: or that?

10:08 interferon: wow

10:08 :pre and :post

10:08 ?

10:11 is that a special case? if you pass a map after the function parameters they're interpreted as contract information?

10:13 rhickey: http://github.com/richhickey/clojure/commit/0ac482878a1dd520cbee2faa0f5f6ab1082ffa76

10:13 only doc is there right now

10:13 the-kenny: :pre and :post looks really cool

10:13 Nice work :)

10:14 interferon: that's great!

10:14 thanks

10:16 is there any way to get type hints to become assertions?

10:16 so if i have a parameter #^String str and i pass it an int, the function throws an exception

10:16 ?

10:22 rhickey: interferon: you could write a macro to do that, but right now type hints are not runtime assertions

10:22 interferon: would you be interested in a patch that checks some special variable *treat-type-hints-as-assertions* when functions are defined?

10:23 rhickey: interferon: no

10:23 interferon: okay

10:23 rhickey: I don't want people to think of type hints as other than that - hints to speed up host interop. Turning them into a type system is a whole different story

10:27 interferon: fair enough

10:44 * angerman wishes the backtraces would be more meaningful :(

10:49 lambdatronic: chouser: you around?

10:51 ah well, perhaps some other time.

11:01 angerman: wow, this should have atken less then 10 minutes, and now I'm trying to figure out why clojure calls nth on an Integer.

11:10 interferon: angerman: throw lots of exceptions to see what's going on

11:11 (throw (Exception. (str (type blah) blah ...)))

11:11 angerman: that's what I've been doing

11:12 but user$eval__xxxx$fn__xxxx.invoke

11:12 that should be one of my anonymously defined functions

11:13 hoeck: angerman: that Exception happens often when you try to destructure a number, like: (let [[a b c] 10] a)

11:14 angerman: hoeck: thanks for the hint. I may have an idea now where to look else

11:15 interferon: does clj-stacktrace help?

11:16 angerman: it's currently runnig and didn't crash yet.

11:16 I think it was (let [[a b] some-seq] ...) instead of (let [a & b] some-seq])

11:17 hoeck: thanks for pointing out that destructuriing might cause the issue

11:21 hoeck: angerman: glad I could help, you also may try to (require 'the.ns :reload) the offending namespace, that puts correct source lines into the stacktrace

11:22 angerman: hoeck: it's a mess. I'm using the slime repl

11:23 hoeck: angerman: :)

11:59 stacktracer: what's the function that inverts a predicate?

11:59 I want a non-nil? predicate ... surely I can do something like: (invert-predicate nil?)

12:00 tomoj: (complement nil?)

12:00 LauJensen: Anything in contrib for quick'n'dirty directory recursion ?

12:01 stacktracer: tomoj: thanks!

12:01 tomoj: LauJensen: as in, give me all the files in this directory tree in depth-first order? :)

12:02 LauJensen: tomoj: yes sir

12:02 tomoj: it's in core

12:02 file-seq

12:02 LauJensen: Basically 'find .' returning a vector or such

12:02 tomoj: file-seq on a File gives you a lazy-seq of Files

12:03 starting with the File you pass and then going in depth-first order

12:04 LauJensen: So I have to supply a file and not just a root dir ?

12:04 tomoj: root dir is fine, they're still Files in java

12:05 LauJensen: ah yes I see

12:05 Thanks

12:05 tomoj: like (file-seq (java.io.File. "/home/tomoj")) gives me a lazy seq starting with my home dir and then going through every single file inside my home dir

12:05 LauJensen: yes sir

12:07 laughingboy: Can anyone here answer some newbie leiningen setup questions?

12:14 cp2: ,(file-seq (File. "."))

12:14 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: File

12:14 cp2: ,(file-seq (java.io.File. "."))

12:14 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission . read)

12:14 cp2: :(

12:19 qed: hmmm, i think today ill spend some time on the packing problem

12:29 npm: ,(org.apache.commons.io.FileUtilstoFile (URL "file" "" "/etc/passwd"))

12:29 well

12:29 tolstoy: Hah. I wonder how clojure bot implements its sandbox?

12:30 the-kenny: tolstoy: Look at the source

12:30 tolstoy: There's source?

12:30 the-kenny: tolstoy: http://github.com/hiredman/clojurebot

12:30 npm: ,(+ 1 1 )

12:30 clojurebot: 2

12:30 the-kenny: http://github.com/hiredman/clojurebot/blob/master/hiredman/sandbox.clj

12:31 npm: ,(org.apache.commons.io.FileUtilstoFile "/etc/passwd")

12:31 clojurebot: java.lang.ClassNotFoundException: org.apache.commons.io.FileUtilstoFile

12:31 npm: oh bette

12:31 r

12:32 ,(org.apache.commons.io.FileUtils.toFile "/etc/passwd")

12:32 clojurebot: java.lang.ClassNotFoundException: org.apache.commons.io.FileUtils.toFile

12:32 npm: well that's good :-)

12:32 tolstoy: ,(slurp "/etc/passwd")

12:32 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission /etc/passwd read)

12:32 npm: heh

12:33 tolstoy: I know nothing at all about that security manager stuff. Cool. Seems worth looking at in some spare moment.

12:33 npm: i do :-) i'm glad it's working

12:33 the-kenny: clojure showed me some parts of the java api which I've never seen before

12:33 like java.net.Authenticator and the security stuff

12:37 npm: plus access to all sorts of cool useful packages like com.trilead.ssh2.*

12:38 TODO implement http://lists.xwiki.org/pipermail/users/2009-August/016934.html in clojure rather than groovy

12:49 qed: anyone have any documentation on reading the java documentation for non-java folks?

12:49 tolstoy: hah hah.

12:50 Generally, look at the "interface" classes, like Map, and in there you'll see "implementing classes" like "HashMap" or "TreeMap" or "LinkedHashMap" and so on.

12:51 But, basically, you only use the interface functions anyway.

12:51 I think that's what I do, aside from looking at actual examples.

13:24 Anniepoo: anybody in the SF bay area, bay area clojure's doing a special thing today

13:25 we realized lots of folks were in that 'i need to fiddle and ask questions' state, so

13:25 today we're meeting in Panera Bread on Millbrae Av. in Millbrae, hanging out with laptops, coding,

13:26 sharing knowledge

13:27 we're also on Second Life at http://slurl.com/secondlife/Belphegor/4/38/82

13:27 cp2: you sure you guys dont wanna run over to dc real quick? :D

13:27 Anniepoo: get an SL account, we're there too!

13:30 www.secondlife.com - download the software (they have linux) and get free account

13:41 the-kenny: Anniepoo: Uhm.. why do you advertise second life to us?

13:42 Anniepoo: only because we're having a clojure meetup there and in the SF bay area

13:43 and cp2 suggested we 'run over to dc real quick'

13:43 SL seemed a more practical solution for him

13:45 ssideris: hello people

13:45 tomoj: you're having a clojure meetup in SL?

13:46 Anniepoo: yes

13:46 tomoj: awesome

13:46 cp2: heh =P

13:46 ssideris: is this the right place for someone (me) who's learning clojure right now to ask newbie questions?

13:46 Anniepoo: http://slurl.com/secondlife/Belphegor/10/43/82

13:46 cp2: yessir

13:48 ssideris: ok i'm trying to right something for doing pattern matching for s-expressions (i'm also new to functional programming)

13:48 (defn mToken [x] (fn [b] (= x b)))

13:48 this would produce matchers matching an exact value

13:49 i also have this: (defn mAny [] (fn [x] (true)))

13:49 tomoj: don't you want more than just a boolean answer?

13:49 ssideris: i'm aiming low for the time being

13:50 trying to get it to say whether it matches or not

13:50 tomoj: ah ok

13:50 ssideris: and i can say "match this OR this" using: (defn mOr [f1 f2] (fn [x] (or (f1 x) (f2 x))))

13:50 and (i'm hoping that) this is for concatenating matchers: (defn m+ [f1 f2] (fn [x y] (and (f1 x) (f2 y))))

13:51 (at this point i'm starting to realize that maybe i should be using pastebin or somthing)

13:51 tomoj: for concatenation I was imagining something that takes however many arguments

13:52 ssideris: good point, will try and refactor

13:52 anyway, so I construct this matcher: (def matcher (m+ (mToken "haha") mAny))

13:52 and I would expect it to match this: (matcher4 "haha" 2)

13:52 but i get this: #<CompilerException java.lang.IllegalArgumentException: Wrong number of args passed to: user$mAny (NO_SOURCE_FILE:852)>

13:53 tomoj: you defined mAny as a zero-arg function

13:53 so (mAny) gives you the matcher

13:53 ssideris: ah!

13:54 tomoj: you could instead do (defn mAny [x] true) if you just want to use mAny directly

13:54 ssideris: ok, so I was passing the function rather than calling it

13:54 this still gets me frequently

13:54 especially when trying to do something smart

13:55 tomoj: hmm, seems there's another problem, though

13:56 oh, you have (defn mAny [] (fn [x] (true)))

13:56 but true is not a function

13:56 ssideris: i think i do need the matcher-producing version of mAny

13:57 tomoj: (defn mAny [] (fn [x] true)) should work

13:59 ssideris: it works! thanks

14:00 qed: anyone have any advice on improving the performance of: http://devinwalters.com/posts/21

14:00 It takes about 30seconds right now

14:02 tomoj: you don't care about the actual values in the chain, do you?

14:04 qed: tomoj: i dont believe so

14:05 tomoj: so you can just use an integer as the accumulator instead of a vector, I'd think?

14:05 not sure how much faster that'd make it go

14:05 the fact that step is a function probably doesn't help either, maybe making it inline would help

14:05 qed: tomoj: do you have any advice for code profiling?

14:05 tomoj: nope :(

14:05 I think there are java tools that work for clojure

14:06 qed: ive been interested in learning how to use profiling tools

14:08 tomoj: yourkit is not free :(

14:09 * qed wonders if it's torrentable :X

14:10 tomoj: well you can download it but it only works for 15 days

14:10 qed: I found something... :X

14:11 tomoj: your code is taking much longer than 30 seconds on my computer :'(

14:11 qed: yeah this is on 4 cores, 8gb of ram

14:11 2.66ghz

14:11 obviously i made some mistakes :)

14:13 tomoj: took it 493s here

14:13 heh

14:13 qed: lol omg

14:30 tomoj: using an integer instead cut it down to 260s

14:30 I think you probably want to try and avoid function calls on integers, use loop and primitives etc

14:40 qed: tomoj: good advice

14:40 tomoj: thank you

14:41 tomoj: not sure how to do all the arithmetic with primitives though

14:42 odd? is bad, and using / is too I think

14:42 bit-and inlines but bit-shift-right doesn't

14:45 that apply at the end looks bad to me as well

14:59 fliebel: Is there a way to make this less verbose? (clojure.contrib.seq-utils/shuffle [:a :b :c :d])

15:00 cp2: (ns foo.bar (:use [clojure.contrib seq-utils :only [shuffle]]))

15:01 (shuffle ....)

15:01 alternatively you can use :as as well

15:01 (ns foo.bar (:use [clojure.contrib seq-utils :as sutils :only [shuffle]]))

15:01 (squtils/shuffle ...)

15:03 tomoj: that's require, no?

15:18 fliebel: cp2: thanks

16:17 * the-kenny doesn't like servers who don't send the Location-Header

16:34 qed: Anyone here familiar with compojure?

16:34 Carkh: yes

17:01 the-kenny: I want to replace the error-handling with exception in clojure-couchdb with return-values.. but what should I return for an error?

17:01 danlarkin: the-kenny: good idea

17:02 the-kenny: Something like {:error true :cause "text"}?

17:02 danlarkin: nil?

17:02 the-kenny: Yeah, but it isn't possible to get the cause of the error with that

17:03 I could also do something like a ref where I can store the errors

17:03 ...but that's not very beautiful in my opinion

17:04 danlarkin: yeah no that's not optimal

17:05 Carkh: why do you want return codes ?

17:05 _ato: the-kenny: My preference is nil for "not found" and exception for real errors (like connection problems or malformed requests or whatever)

17:05 the-kenny: I don't like the exceptions... and some others here too

17:05 _ato: hm..

17:05 Carkh: ato : what if you found a nil ?

17:06 the-kenny: _ato: But then you would have to define "not found" ;)

17:07 _ato: Carkh: maybe do the same thing as Clojure, have an optional argument you can set for not found which defaults to nil?

17:07 Carkh: chouser made a library with common lisp style conditions

17:07 though that's is the same as exceptions, only restartable

17:08 the-kenny: _ato: But couchdb returns some useful informations for an "empty" view, like total document count and such things.

17:09 _ato: hmm. I think Clutch always returns a map.. with like {:rowcount 1234, :rows [...]}

17:09 Carkh: the-kenny : so hat are the drawbacks of exceptions compared to the drawbacks of error calls ?

17:09 the-kenny: Yes, that's the return data of couchdb

17:10 Carkh: *error codes

17:10 the-kenny: Carkh: Exceptions aren't very "functional".

17:11 Carkh: well if you have a pure function, and it raises an exception, you may expect it to always do so

17:11 what's not functional in that ?

17:12 i woudn't want to use a library that returns error codes, that means i need to check these at each nested function, or raise an exception myself

17:12 or use monads =/

17:13 the-kenny: Exceptions are way more verbose than error-codes. You can just ignore errors, but you can't ignore exceptions

17:13 _ato: I tend to be doing a number of different things:

17:13 1. getting a single document

17:13 2. getting a list of documents

17:13 Carkh: just ignore errors ? yuk !

17:13 _ato: 3. doing updates

17:14 when getting a single document I don't usually care about the row count, so nil is fine

17:14 when getting a list of documents, I can return a list (could be empty list). This could have the row count on it as metadata

17:15 when updating I probably want exceptions as not-found doesn't make sense there. For conflicts I probably want two different update functions, one which automatically retries with a pure function (think swap! and atoms) and another that lets me decide what to do with the conflict (eg ask the user or whatever)

17:15 Carkh: anyways if you want to ignore errors nothing prevents you from makeing a function or macro ignore-errors

17:16 the-kenny: Carkh: Nothing prevents me from modifying my fork of clojure-couchdb either ;)

17:17 Carkh: (defn ignore-errors [func & params] (try (apply func params) (catch Exception e nil)))

17:17 heh sure, you're king with your code, i'm just saying =)

17:18 the-kenny: hm.. I've never thought about metadata for clojure-couchdb

17:19 the erlang-way would be something like {error, data} and doing pattern-matching on it.

17:19 ssideris: guys, say I have a bunch of functions as a list and a list. I want to apply each function to the corresponding element of the list (based on position). Any ideas?

17:20 the-kenny: ssideris: Something like (map #(%1 %2) function-list data-list)?

17:20 _ato: ,(map inc [1 2 3])

17:20 clojurebot: (2 3 4)

17:20 _ato: oh

17:20 bunch of functions

17:21 the-kenny: ,(map #(%1 %2) [inc dec inc dec] [1 2 1 2])?

17:21 clojurebot: (2 1 2 1)

17:21 ssideris: the-kenny: yeah, i think that would do

17:21 thanks

17:21 the-kenny: You're welcome

17:21 ssideris: ultimately i'd like to see if they all returned true

17:21 but i think constructing the list of results is the first step

17:22 the-kenny: ssideris: (every? true? list)

17:22 ssideris: so elegant!

17:22 :-)

17:23 the-kenny: Lisp is very elegant :)

17:23 s/Lisp is/Lisps are/

17:24 gbt: well they're very elegant when you know what you're doing, which I don't, but thats why I hang out here :)

17:24 ssideris: i'm new to lisp in general, I had tried learning Common Lisp in the past but Clojure really motivates me because I already know the java standard lib

17:28 triyo: ,(into-array ["/xxx" "/yyy"])

17:28 clojurebot: #<String[] [Ljava.lang.String;@3242c8>

17:28 triyo: hhm, I get java.lang.NoSuchMethodError: org.springframework.util.Assert.noNullElements([Ljava/lang/Object;Ljava/lang/String;)

17:29 I thought is said String array of String elements

17:30 am I misusing into-array? All I do is pass the (into-array ["/xxx" "/yyy"]) onto the java class through interop

17:31 the method of the class expects a String array

17:31 nickpad: wondering if someone can help me out with some java interop stuff - trying to call a java constructor method Foo(int labels[])

17:32 the-kenny: triyo: Maybe you want to add the type to the array?

17:32 triyo: hehe, nickpad: I'm asking a similar question :)

17:32 the-kenny: Oh wait

17:33 triyo: ,(into-array ["/xxx" "/yyy"])

17:33 clojurebot: #<String[] [Ljava.lang.String;@b8229c>

17:33 nickpad: i've tried (new Foo (int-array [1 2 3]) but that gives me an illegal argument exception

17:33 tomoj: triyo: hmm

17:33 google that exception

17:33 the-kenny: nickpad: You forgot the int

17:33 oh stop

17:34 I read the constructor wrong..

17:36 triyo: tomoj: hmm googled, that sounds dodgy.

17:36 tomoj: do you have multiple versions?

17:36 I don't understand the error, I know that "[Ljava/lang/Object;" means an array of Objects, but what's "[Ljava/lang/Object;Ljava/lang/String;" mean?

17:36 triyo: I used leiningen to download the depenedencies

17:37 I'l have a look at the lib/ dir quick

17:38 It means an Object array of Strings

17:38 new spring ver has rather a String array of Strings of course

17:39 yup I think I see a lib culprit

19:03 ssideris: hello, I've written this very basic set of functions for matching s-expressions: http://pastebin.ca/1712672

19:03 and i was wondering whether there is anyway to write something like: (def matcher (m=+ 1 matcher))

19:04 of course that woudl not work as it is since when def-ing matcher, the symbol matcher is not bound yet

19:04 the-kenny: ssideris: Maybe if you do a "(declare launcher)" above this def?

19:05 ssideris: hm, no i still get the same error

19:06 the-kenny: um sorry, I meant (declare matcher)

19:06 ssideris: yeah, i got that :-)

19:06 but it didn't work

19:08 also i think that maybe i dont really want to refer to matcher

19:09 but to the function that m=+ produces

19:09 which is anonymous anyway!

19:12 tomoj: ssideris: I'm confused

19:12 _ato: maybe: (def matcher (m=+ 1 (fn [& args] (apply matcher args))))

19:13 ssideris: tomoj: about the purpose of the code, or my last question?

19:13 tomoj: the purpose

19:13 _ato's rendering clears it up a bit

19:13 your (def matcher ..) above confused me, a circular definition

19:14 ssideris: the idea is to try and produce a recursive matcher

19:14 so if (m=+ 1 2) returns true when passed (1 2)

19:14 (def matcher (m+= 1 matcher))

19:15 would match (1 1) and (1 1 1 1) etc

19:15 _ato: hrmm

19:16 I thought it would match (1 (1 (1 (1 ...

19:16 but maybe I'm misunderstanding

19:17 ssideris: erm, possibly, I'm basically borrowing ideas from parser combinators

19:17 tomoj: so, I guess you want a fixed point of (partial m+= 1) ?

19:18 ssideris: tomoj: give a second to read up on partial

19:21 mudphone: Hiya folks, anyone know where I can find swank-clojure.jar files for download?

19:22 ssideris: maybe what i'm asking for is slightly misguided: the main purpose of being able to define matchers recursively would be to able to say "match this multiple times"

19:23 but maybe it's better to leave that out and create a few other functions tha implement "match at least once", "optional match multiple times", "match exactly X times" etc

19:23 tomoj: Z combinator works

19:23 but this is probably not the best approach :D

19:23 _ato: mudphone: http://clojars.org/repo/swank-clojure/swank-clojure/1.1.0-SNAPSHOT/

19:23 tomoj: er, Y combinator, but applicative order of course

19:24 mudphone: _ato: gracias!

19:24 should have remembered to check clojars

19:25 ssideris: yeah my understanding is that Y combinator is a mythical creature that allows you to do recursion on anonymous functions

19:25 but that's all :-(

19:25 sorry, functional newbie as well as clojure newbie

19:25 _ato: I should add a download link the clojars jar pages so that it's more obvious how to just get the jars without using Leiningen/Maven/Ivy etc

19:26 tomoj: hmm

19:26 actually it doesn't seem to work

19:26 ssideris: oh ok

19:27 what do you think about the approach i described above?

19:27 mudphone: _ato: swank-clojure is step one for me... then it's on to lein + swank clojure project

19:28 hope that's the right order

19:29 tomoj: ssideris: sounds reasonable

19:29 but I'm now going to go figure out how to make the Y combinator work for this :)

19:30 ssideris: well let me know if you do!

19:31 tomoj: I think the issue is that this matcher takes arbitrarily many arguments

19:32 that's one thing that puzzles me about your code so far

19:32 why (m8 1 1 1 1) instead of (m8 '(1 1 1 1)) ?

19:33 ssideris: dunno, less parenthesis

19:33 no good reason really

19:33 do you think it would result to cleaner code if I pass one argument?

19:33 tomoj: I think it would make my Y combinator trick easier :)

19:33 but, didn't you say the goal is pattern matching on sexps?

19:34 so the argument to a matcher would presumably be a sexp?

19:34 ssideris: indeed...

19:34 ok let me change it

19:35 erm just a sec

19:35 tomoj: I don't really know anything about pattern matching, so don't listen to me

19:35 ssideris: me neither, this my educational project

19:36 if I change m=+ to accept a single param, then don't i lose the ability to say:

19:36 (m=+ 1 2 (m_) 4 5)

19:36 m_ being the "any" matcher

19:36 tomoj: well I wouldn't think m=+ should accept a single param

19:36 rather the return value of m=+

19:37 so that ((m=+ 1 2 (m_) 4 5) [1 2 3 4 5]) is true for example

19:37 but again, I dunno what I'm talking about. I think making that change actually also removes the need for the Y combinator trick :(

19:38 ssideris: ok say I write m=+ differently so that it accepts a list

19:39 I would then have to define amatcher as: (m=+ '(1 2 (m_) 4 5))

19:39 but the ' would prevent the evaluation of (m_)

19:39 so that expression would only produce a half-baked matcher

19:39 tomoj: well, again, I think m=+ is fine taking however many arguments

19:40 that makes sense to me

19:40 ssideris: ok, sorry I thought you said otherwise

19:40 tomoj: but I would think that the return value of m=+ should be a function of one argument

19:41 ssideris: ah ok, so that would make a difference in the invocation of the matcher, not the definition

19:41 tomoj: right

19:41 ssideris: so for (def m7 (m=+ 1 2 (m-regex #"(ha)+") 4 5))

19:41 you do: (m7 '(1 2 "iopj" 4 5))

19:41 ok makes sense

19:42 tomoj: I dunno if that's actually better or not

19:42 isn't that how parser combinator libraries usually work?

19:42 ssideris: the things i've read are for parsing strings

19:42 tomoj: I mean, the parsers accept lists of tokens rather than arbitrarily many arguments

19:42 oh, hm

19:43 have you seen fnparse yet?

19:43 ssideris: nope

19:43 * ssideris googles

19:43 tomoj: maybe you might get some ideas from it http://github.com/joshua-choi/fnparse

19:43 I still haven't been able to wrap my head around it

19:43 ssideris: thanks!

19:44 the paper url is broken

19:44 i mean the academic paper he's linking to

19:44 tomoj: extra parenthesis

19:45 got href'd wrong

19:45 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=

19:45 ssideris: oh it *is* about parser combinators

19:46 cool

19:47 tomoj: the code you pasted is the initial steps toward a parser combinator library, right?

19:47 I don't even know the difference between this and pattern matching

19:47 with pattern matching do you end up with a map of bindings?

19:48 ssideris: yes, i suppose it is, although i was intending to leave it to the level of s-expr, didn't want to use it for strings

19:49 i think in pattern matching (as per haskell) you provide some values to fill the gaps

19:50 so the pattern is filled by the data provided

19:50 tomoj: I think I remember seeing something about pattern matching in clojure somewhere

19:53 _ato: ssideris: http://gist.github.com/255178 :-P

19:54 tomoj: atoms? :(

19:56 _ato: tomoj: if you can do it without atoms/vars/refs and without changing the structure of the m=+ function, I'll be very impressed

19:57 you need a level of indirection somewhere so you can bind the value of "this" after you close over it

19:58 tomoj: I was imagining m8 as curried

19:58 but if that is the case, its return value has to be a function

19:58 which is truthy :/

19:59 which would bring me to fnparse's monads

20:02 we can do (apply m=+ (repeat 1)) but that's cheating I guess?

20:02 pretty awesome that we can apply a function to an infinite sequence...

20:02 I'm surprised that works

20:03 _ato: ah, yeah that's a nicer way of expressing it. I should have thought of that

20:05 tomoj: I hadn't realized [& args] would accept a lazy seq

20:08 ,(take 10 (apply (fn [a b & args] (concat [a b] args)) (concat [1 2] (repeat 1))))

20:08 clojurebot: (1 2 1 1 1 1 1 1 1 1)

20:08 tomoj: so we have functions which not only can take an arbitrary number of arguments, but which can in fact take an infinite number of arguments.. cool!

20:16 ssideris: wow

20:16 so that solves it doesn't it?

20:18 tomoj: I don't really like that solution :/

20:19 well, maybe if you wrap it in m* or something

20:21 m+ perhaps

20:21 it doesn't work like I'd expect

20:22 if we do (defn m+ [x] (apply m=+ (repeat x)))

20:22 ((m+ 1) 1 1 1 1) works, but (m=+ 3 (m+ 1) 4) doesn't

20:22 it matches 3 1 4 but not 3 1 1 4

20:23 actually, I think this is just because m=+ can't be composed

20:24 I would expect (m=+ 3 (m=+ 1 2 3) 4) to match 3 1 2 3 4, is it supposed to?

20:24 ssideris: yes it is

20:24 Intertricity: does clojure have anythign like python slices?

20:24 ssideris: does it not?

20:24 Intertricity: *anything

20:24 tomoj: no, it doesn't

20:24 Intertricity: like "blah12342314"[:3]

20:24 tomoj: oops, talking to ssideris, not you, Intertricity

20:24 Intertricity: tomoj, ah ok :)

20:24 tomoj: Intertricity: but, no, there is no special syntax for that

20:25 ,(take 3 "blah")

20:25 clojurebot: (\b \l \a)

20:25 Intertricity: oooh that's just as good

20:25 ,(str "hello")

20:25 clojurebot: "hello"

20:25 tomoj: ,(take 3 (drop 2 "blaarghhglll"))

20:25 clojurebot: (\a \a \r)

20:25 Intertricity: :o

20:26 tomoj: also there's subs for strings

20:26 Intertricity: ok that's the coolest bot I've seen so far xD

20:26 tomoj: ,(subs "blaarghhll" 3 6)

20:26 clojurebot: "arg"

20:26 Intertricity: ,(subs "blaaarghdfafad" 0 3)

20:26 clojurebot: "bla"

20:26 Intertricity: that would work perfectly

20:27 what about turning string characters into a list I can iterate through?

20:27 ssideris: tomoj: i've changed the code slightly: http://pastebin.ca/1712745

20:27 tomoj: Intertricity: just iterate through them

20:27 Intertricity: tomoj, ahh ok, thanks :D

20:27 _ato: ,(map identity "blargh")

20:27 clojurebot: (\b \l \a \r \g \h)

20:27 _ato: ,(apply str (map identity "blargh"))

20:27 jasapp: ,(seq "asdf")

20:27 tomoj: strings are seqable, so pretty much anything that expects a sequence will accept a string

20:27 clojurebot: "blargh"

20:27 (\a \s \d \f)

20:28 ssideris: just to have the matcher from m=+ accept a single param

20:28 tomoj: I think that might fix the problem I just saw

20:28 _ato: ,(apply str (take-while #(.isLetter %) "hello7bar"))

20:28 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: No matching field found: isLetter for class java.lang.Character

20:29 Intertricity: tomoj, do you know if ikvm's .net support is any good?

20:29 _ato: ,(apply str (take-while#(Character/isLetter %) "hello7bar"))

20:29 clojurebot: java.lang.Exception: Unable to resolve symbol: take-while# in this context

20:29 _ato: ,(apply str (take-while #(Character/isLetter %) "hello7bar"))

20:29 clojurebot: "hello"

20:29 Intertricity: I have a project I want to use clojure to learn with, but it requires a .net library :\

20:29 tomoj: Intertricity: dunno what ikvm is, and dunno anything about .net, sorry

20:29 I think there is a version of clojure running on the CLR, though?

20:30 aluink: i'm trying to compile a simple app in a subfolder app/hello.clj i'm doing (compile 'app.hello) from the Repl, but continually get classpath errors. anyone got a minute or two to give me a hand?

20:30 tomoj: lots of clojure libraries probably don't work with it, though, but you can write your own stuff

20:30 _ato: http://wiki.github.com/richhickey/clojure-clr

20:31 Intertricity: tomoj, http://www.ikvm.net/

20:31 aluink: i'm doing what i'm told to do on this page, http://clojure.org/compilation

20:31 hiredman: compile?

20:31 clojurebot: the unit of compilation in clojure is the namespace. namespaces are compiled (not files). to compile a namspace the namespace needs to be on the classpath and so does ./classes/ (and the directory needs to exist) because clojure writes the class files to that directory. http://clojure.org/compilation

20:32 aluink: i've exported CLASSPATH=./classes:./

20:32 _ato: aluink: also make sure you have (ns app.hello) at the top of app/hello.clj

20:32 aluink: and yes, classes does exist

20:33 hiredman: lisppaste8: url?

20:33 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

20:33 hiredman: pastebin somesomething (errors, code, shell commands, etc)

20:34 tomoj: ssideris: hmm, I'm seeing new problems

20:34 lisppaste8: aluink pasted "hello" at http://paste.lisp.org/display/92007

20:35 ssideris: tomoj: i'm all ears (or eyes?)

20:35 aluink: _ato: see the paste

20:35 tomoj: ssideris: try this ((m=+ 3 (m=+ 1 2 3) 4) '(3 1 2 3 4))

20:36 oh, wait, ((m=+ 3 (m=+ 1 2 3) 4) '(3 (1 2 3) 4)) works

20:36 which one is supposed to work?

20:36 ssideris: against what?

20:36 sorry...

20:36 you have the parameter right there

20:37 _ato: aluink: java -cp clojure.jar:.:classes -Dclojure.compile.path=classes clojure.lang.Compile app.hello

20:37 Intertricity: has anyone here played with ClojureCLR?

20:37 hiredman: :|

20:38 ssideris: what is the exception, how/when do you see the exception and how are you starting clojure?

20:38 _ato: aluink: otherwise please paste the command you're using and the error

20:38 ssideris: tomoj: well, the first should return false rather than throwing an exception

20:39 hiredman: you mean aluink?

20:39 hiredman: ssideris: I must

20:39 <-- full of nyquil

20:39 tomoj: ssideris: ah, yes

20:40 ssideris: tomoj: it's probably because m=+ assumes the correct amount of tokens

20:40 tomoj: well..

20:40 actually

20:40 try this

20:40 ((m=+ 1 2) '(1))

20:40 :D

20:40 it assumes it's being given something seqable, anyway

20:40 aluink: _ato: ok, that worked, but this is what i was doing...

20:40 lisppaste8: aluink pasted "process" at http://paste.lisp.org/display/92008

20:41 ssideris: tomoj: so the use of map is what creates the problems

20:41 tomoj: yep, it cuts off at the sorter seq

20:41 hiredman: aluink: -cp and CLASSPATH are mutually exclusive

20:41 aluink: _ato: i wonder if it was picking up my export and/or was it that -D that did the trick

20:41 hiredman: if you use -cp then CLASSPATH is ignored

20:42 tomoj: so similarly ((m=+ 1 2) '(1 2 3)) is true

20:42 aluink: hiredman: ahhh!!!

20:42 hiredman: yeah

20:42 ssideris: tomoj: so I should return false if it's not seqable and if the sequences are of different lenghts

20:42 aluink: i didn't know that, where is that documented?

20:42 man java1

20:42 !

20:42 tomoj: ssideris: that sounds like it would fix it, yeah

20:43 _ato: "Specifying -classpath or -cp overrides any setting of

20:43 the CLASSPATH environment variable." -- man java

20:43 tomoj: though you'll be going through the sequence twice and holding the head :/

20:43 aluink: to do what i was doing, i should have done -cp clojure.jar:$CLASSPATH

20:44 that's kinda've annoying, oh well...thanks for pointing that out!

20:45 hiredman: clojurebot: -cp and CLASSPATH |are| mutually exclusive

20:45 clojurebot: You don't have to tell me twice.

20:45 hiredman: now it's documented there

20:48 aluink: how is that info retrieved?

20:48 better yet, where can i find docs on working with clojurebot?

20:49 ssideris: MEIN FUEHRER, IT WORKS!

20:50 hiredman: clojurebot: -cp and CLASSPATH?

20:50 clojurebot: classpath is (System/getProperty "java.class.path")

20:50 hiredman: hmmm

20:50 _ato: hehe

20:50 hiredman: clojurebot: -cp and CLASSPATH

20:50 clojurebot: -cp and CLASSPATH are mutually exclusive

20:50 ssideris: tomoj: http://pastebin.ca/1712761

20:50 aluink: you kinda have to know to ask that question though right?

20:50 hiredman: clojurebot: -cp?

20:50 clojurebot: Excuse me?

20:50 _ato: clojurebot: -cp

20:50 clojurebot: Pardon?

20:51 _ato: heh

20:51 hiredman: clojurebot: exclusive?

20:51 clojurebot: Gabh mo leithscéal?

20:53 tomoj: ssideris: you'll want to replace seq? with sequential? I think

20:54 vectors aren't seqs so ((m=+ 3 4) [3 4]) doesn't work with seq?

20:54 ssideris: oh ok

20:54 why is that?

20:55 tomoj: lists are their own seqs

20:55 hiredman: clojurebot: -cp and classpath?

20:55 clojurebot: -cp and CLASSPATH are mutually exclusive

20:55 tomoj: ,(let [lst '(1 2 3)] (identical? lst (seq lst)))

20:55 clojurebot: true

20:55 tomoj: ,(let [v [1 2 3]] (identical? v (seq v)))

20:55 clojurebot: false

20:55 tomoj: vectors aren't

20:56 nor hashmaps, strings, etc

20:56 hiredman: win 11

20:57 _ato: ,(sequential? "foo")

20:57 clojurebot: false

20:57 tomoj: hmm

20:57 yeah I just noticed that too

20:57 I remember asking this question before, but don't remember the answer -- how do we test for seqability?

20:59 chouser: there is a 'seqable?' on contrib, but it's rarely the right thing to use.

21:00 tomoj: is "will this thing work with the seq library" not the right question to ask?

21:01 chouser: righ

21:01 right

21:01 tomoj: oh, yes, I see you are right in this case

21:01 if we did a test for seqability, we couldn't use strings as literals in the patterns

21:01 chouser: because of my complex and persuasive argument.

21:01 :-)

21:02 *most* of the time if the code is going to choose between two valid actions, you want something more specific than seqability

21:02 tomoj: as it is we can't use lists, and with sequential? can't use vectors

21:03 chouser: perhaps 'coll?'

21:03 tomoj: what all implements Sequential? lists, vectors, ...

21:03 huh, NOT seqs

21:03 hiredman: not strings

21:04 tomoj: well, I dunno what the right test is, then

21:04 ssideris: this is so confusing... we need a comparison table

21:04 tomoj: ,(sequential? (seq []))

21:04 clojurebot: false

21:04 tomoj: but

21:05 ,(sequential? (iterate inc 1))

21:05 clojurebot: true

21:05 tomoj: :(

21:05 I cast you out, sequential?

21:05 _ato: ,(seq? (seq []))

21:05 clojurebot: false

21:05 tomoj: wat

21:05 _ato: ;-)

21:05 ,(seq [])

21:05 clojurebot: nil

21:05 tomoj: ooh

21:06 ok, I welcome you back in, sequential?

21:06 so seqs are sequential, that's good :)

21:06 qed: maybe this is a dumb question, but....how are colls different from seqs?

21:06 BrandonW: hello, i've got a quick question about functional programming, if that's okay :)

21:07 ssideris: seqs are lazy lists, right?

21:07 tomoj: ,(coll? (seq [1]))

21:07 clojurebot: true

21:07 tomoj: wait, what? I thought that would be false

21:07 qed: lol

21:07 tomoj: PersistentVector$ChunkedSeqs are colls I guess

21:08 ok, but {} is a coll and {} is not a seq

21:08 (and similarly [] is a coll but not a seq)

21:08 qed: #{} seems like it wouldnt be a coll

21:08 _ato: public interface IPersistentCollection extends Seqable

21:08 qed: but i guess ordering really has nothing to do with it?

21:08 * ssideris is firing up Inkscape to make this into a table

21:08 BrandonW: if you want to make a library along the lines of a pdf editor, how would you write a functional library for editing PDFs, if each operation would return an entirely new pdf as per functional programming idioms. Wouldn't that be a lot of memory overhead? I barely know anything about functional programming, I'm just trying to wrap my head around the concepts :)

21:08 brb

21:09 _ato: colls needs to implement count, cons, empty, equiv and be seqable

21:09 tomoj: presumably you wouldn't write out the entire pdf to disk every time a change is made

21:09 if you have some in memory representation of a pdf in terms of persistent data structures, the new pdfs aren't really "entirely" new

21:09 qed: _ato: they need to implement all of those?

21:09 tomoj: they can share structure

21:09 _ato: all seqs are colls

21:10 and all colls are seqable

21:10 qed: but not all colls are seqs

21:10 _ato: right

21:10 qed: ok

21:11 tomoj: where's the clojure ring benchmark?

21:12 chouser: ~classes

21:12 clojurebot: Gabh mo leithscéal?

21:12 tomoj: I found one in swannodette/clojure-benchmarks but I'm looking for rhickey's

21:14 chouser: This may help understand relationships between collection types: http://tinyurl.com/clojure-classes

21:14 except ... it's a bit out of date and potentially a bit overwhelming.

21:14 tomoj: I think a table would be nice

21:14 but I want to generate it programmatically

21:15 s/svg/html/ and it's easy :)

21:15 chouser: right -- the code is there -- go for it.

21:19 qed: ah, clojure documentation... such fun

21:19 tomoj: qed: are you the one working on that doc wiki project?

21:20 qed: yeah, well, attempting to, i suck at clojure still, and compojure isn't easy for me, but it's slowly coming along

21:20 ssideris: so strings are not sequential?

21:20 qed: im trying to get a basic structure for the site down

21:21 ssideris: ,(sequential? "hello")

21:21 clojurebot: false

21:21 tomoj: qed: well, good luck, I'm excited :)

21:21 ssideris: I think this is a good thing for your matchers

21:21 qed: tomoj: hey man, ill need some help if you're up to it! :)

21:22 tomoj: if strings were sequential, ((m=+ \a \b) "ab") would work, but ((m=+ 1 "foo" 2) '(1 "foo" 2)) wouldn't

21:22 qed: is it in git somewhere yet?

21:22 qed: you can clone the repo and just start making markdown files with the name of the forms, follow the template and badda bing badda boom

21:22 ya one sec

21:22 http://github.com/defn/cljex

21:23 tomoj: awesome, you bought that domain name as well?

21:23 qed: i was thinking it might be a better idea to get the docstrings automatically and put them into the files so we dont need to update that part later

21:23 yeah getclojure.org/com

21:25 ssideris: here's a table: http://www.stathis.co.uk/private/seqs.svg

21:26 have i missed anything?

21:26 firefox just shows me the source of the svg!

21:27 silly firefox

21:27 the-kenny: OmniWeb does it too.

21:27 * ssideris uploading bitmap version

21:27 _ato: your webserver is serving it as text/plain

21:27 BrandonW: tomoj: that sounds what I was thinking. I had read something about if you program functionally, everything can be passed by reference because the referenced objects will never be changed, and if you do need to change it, there is a cheap way to clone it with a minor modification

21:28 so each successive change of the pdf would not create an entirely new pdf in memory, but rather take the original pdf and append whatever changes are needed, right?

21:28 tomoj: something like that, yeah

21:28 ssideris: http://www.stathis.co.uk/private/seqs.png

21:28 tomoj: if you change it, you get a new object, but it has references inside it to parts of the old object

21:28 and since none of these objects can ever change, this is not a problem

21:29 _ato: http://meshy.org/~ato/tmp/seqs.svg

21:29 tomoj: why doesn't apache know how to serve svg by default? :/

21:29 _ato: ssideris: you missed {}

21:30 tomoj: there are other things I'd like to see on a table as well

21:30 counted? for instance

21:31 hiredman: ,(coll? (seq [1 2]))

21:31 clojurebot: true

21:31 hiredman: your table is missling a dot

21:31 BrandonW: okay thanks for the information :)

21:32 i'm trying to decide between clojure vs scala in the next language i want to learn

21:32 tomoj: that sounds like an interesting project, BrandonW

21:32 the pdf stuff I mean

21:32 _ato: ,(counted? '(1 2))

21:32 clojurebot: true

21:32 ssideris: tomoj: thanks

21:32 BrandonW: oh it was mostly a hypothetical question at this point

21:32 _ato: ,(counted? (cons 1 (cons 2 ()))

21:32 clojurebot: EOF while reading

21:32 tomoj: the choice between clojure vs scala is trivial, so uninteresting :P

21:32 _ato: ,(counted? (cons 1 (cons 2 ())))

21:32 clojurebot: false

21:32 BrandonW: java has pretty good pdf tools already that i'm sure could be used from clojure

21:32 _ato: difference between lists and cons cells

21:32 tomoj: yeah, but I bet they suck

21:32 hiredman: clojurebot: scala {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

21:32 clojurebot: Any = 1

21:33 tomoj: what sounds interesting to me is coming up with a persistent representation of pdf documents

21:33 BrandonW: it was more a question on the inner workings of functional language not slowing you down when you have a large-ish object whose state would be changing a lot (in an oop paradigm, anyways)

21:33 from what i've heard/used of it, it works pretty well

21:33 tomoj: yeah

21:33 BrandonW: but of course, it isn't idiomatic clojure, so it could be improved :)

21:33 tomoj: there is some slowdown, but it's not bad

21:33 ssideris: tomoj: ok, counted?... what else?

21:34 _ato: what does {} do?

21:35 tomoj: dammit, why did I think it was a good idea to ditch the emacs-starter-kit. now swank-clojure-project doesn't even work, and lein-swank is apparently broken atm

21:35 hiredman: #scala.log:2009:Dec:03:16:41:22 dibblego : dcsobral, FWIW, I've given up on expecting a usable Scala core library, to save disappointment

21:35 _ato: ssideris: {} is an empty map

21:35 I guess there's also reversible?

21:36 and associative?

21:37 oh and ifn? of course

21:37 ,(ifn? [])

21:37 clojurebot: true

21:37 ssideris: i thought all maps started with #

21:37 _ato: ,(ifn? ())

21:37 clojurebot: false

21:37 ssideris: #{}

21:37 _ato: that's a set, not a map

21:37 ssideris: oh eys

21:37 _ato: ,{:foo 1, :bar 2}

21:37 clojurebot: {:foo 1, :bar 2}

21:37 ssideris: *yes

21:37 _ato: ,#{:foo :bar}

21:37 clojurebot: #{:foo :bar}

21:38 _ato: oh and there's also: sorted?

21:38 ,(sorted? #{})

21:38 clojurebot: false

21:38 _ato: ,(sorted? (sorted-set))

21:38 clojurebot: true

21:38 tomoj: damn

21:39 I was just about to say that the only other one that seemed relevant was sorted? (just grepped the ns-publics in clojure.core for "?" :D)

21:39 I mean we have chunked-seq? and vector? and some others, but they don't seem that valuable

21:39 ssideris: i'm starting to think that doing this in svg is not such a good idea

21:40 tomoj: I am trying to start a project to do it in html, but can't get a repl up for some reason

21:41 ssideris: it would be nice to have another column with a brief explanation of what each test means?

21:43 tomoj: oh, seems we need swank-clojure.jar in lib/ now for swank-clojure project

21:43 :/

21:45 j3ff86: what does -> do?

21:47 nevermind

21:49 ssideris: which collection implements Sorted?

21:50 j3ff86: different from sort?

21:51 tomoj: well, there are sorted sets and sorted maps

21:51 perhaps others

21:52 _ato: ,(sorted? (sorted-set))

21:52 clojurebot: true

21:52 _ato: ,(sorted? (sorted-map))

21:52 clojurebot: true

21:52 _ato: ,(sorted? (array-map))

21:52 clojurebot: false

21:52 _ato: ,(sorted? (hash-map))

21:52 clojurebot: false

21:52 _ato: ,(type {})

21:52 clojurebot: clojure.lang.PersistentArrayMap

21:53 ssideris: tomoj: where you going to automate the html table?

21:53 i mean generating it

21:54 tomoj: yup

21:56 ssideris: anyway, here's the updated hand-made version: http://www.stathis.co.uk/private/seqs.png

21:57 http://www.stathis.co.uk/private/seqs.svg

21:59 tomoj: thank you for making me learn how to use conkerors "view internally as mime type" feature :)

22:10 ssideris: hahahaha

22:11 tomoj: what would you use for generating html?

22:13 tomoj: well, I haven't done much of it, but I think I like enlive

22:13 quizme: hi

22:13 tomoj: though that might not really count as "generating html"

22:13 instead you have your html out in html files (where it belongs :P) and you apply transformations to it to add in the dynamic stuff

22:13 quizme: is it better to write in a functional (stateless) way or object-oriented way in clojure ?

22:14 tomoj: certainly the former...?

22:15 ssideris: tomoj: the clojure API documentation is not very clear on the data structure test functions

22:15 quizme: why is that ?

22:16 tomoj: well, it's not easy to write in an object-oriented way in clojure

22:16 ssideris: tomoj: "this tests if the collection implements interface X" doesn't mean much to most people

22:16 especially beginners

22:16 tomoj: indeed

22:17 counted? is good

22:17 ssideris: are you aware of any texts that explain things a bit more clearly?

22:17 tomoj: nope :/

22:17 the source?

22:17 having a list of the methods in the mentioned interfaces to go along with the table would be nice

22:18 though from a clojure perspective those should be de-emphasized I guess

22:19 _ato: quick and dirty version: http://meshy.org/~ato/tmp/colls.html

22:21 quizme: tomoj: are you writing a tutorial ?

22:21 tomoj: nope

22:22 was going to make a chart like _ato's

22:22 your htmlize is sexy, _ato

22:23 ssideris: _ato: nice

22:23 tomoj: so lists (and seqs) are the only things that are their own seqs?

22:25 the reduce in the agent-ring function at http://github.com/swannodette/clojure-benchmarks/blob/master/thread-ring/thread-ring.clj seems absolutely brilliant to me

22:25 _ato: ,(seq? (range 10))

22:25 clojurebot: true

22:25 tomoj: though it took me a while to understand it

22:26 oh, Conses are there own seqs too

22:26 oh, Conses ARE seqs

22:26 well of course they are. now I've confused myself :(

22:27 it's a tautology that seqs are the only things that are their own seqs

22:31 does anyone else thing that reduce is brilliant?

22:32 qed: like.. (reduce)?

22:32 it's just a foldr right?

22:33 tomoj: ah, english

22:33 qed: you know...foldr...reduce has been around for awhile in various forms

22:33 tomoj: it's a foldl, though, right?

22:33 qed: err yeah sorry

22:33 i always mix them up

22:34 tomoj: but what I meant was, does anyone else think that that reduce is brilliant

22:34 qed: ohhh, that *that* reduce

22:34 tomoj: as in, that reduce over there: http://github.com/swannodette/clojure-benchmarks/blob/master/thread-ring/thread-ring.clj

22:34 qed: i dont understand agents yet :\

22:34 * qed booksmarks

22:34 qed: bookmarks

22:35 ssideris: i think i'm going to bed

22:35 thanks for all your help guys

22:35 i still have loads to learn

22:35 bye-bye!

22:35 _ato: heh, cute

22:36 tomoj: I would've never thought to use reduce there

23:07 duncanm: la la la

23:44 quizme: what's clojure's way of doing object-oriented stuff?

23:44 tomoj: does not doing object-oriented stuff count as a way of doing object-oriented stuff?

23:44 maybe the new stuff in the new branch is what you're looking for, I dunno

23:45 quizme: clos stuff

23:45 tomoj: we have multimethods

23:45 for dynamic dispatch

23:46 and the new branch has some new stuff in that area as well

Logging service provided by n01se.net