#clojure log - Oct 24 2009

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

0:01 hiredman: http://pixel-shaker.fr/en/2009/09/representation-dimages-clojure-et-java-premiere-partie/

0:03 somnium: how do you specify multiple constructors? variable arity, variable type

0:03 or different, not variadic

0:04 hiredman: it turns out I missed redirecting a call to LispReader/read in LispReader/readDelimitedList so none of my incremental developed and tested code was ever really tested

0:04 somnium: but this is good, thans

0:04 hiredman: erm

0:04 have you read the api docs?

0:04 somnium: yeah

0:05 hiredman: there is a :constructors keyword

0:05 somnium: yes

0:05 hiredman: and that didn't jump out as a way to implement constructors?

0:07 somnium: ostensibly yes, it did connect that :constructors and the vectors that followed were linked in a meaniful way

0:08 but it didn't jump out how to do [Object Object String] [] [Object String Interface] [] [Object ...]

0:08 http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples/Java_Interaction#genclass

0:08 and this didn't help

0:09 though it did compile in slime, only to blow up in ant

0:09 hiredman: http://clojure.org/compilation

0:11 somnium: note the most complicated constructors invocation in the examples

0:15 hiredman: how much more do you want the constructor to do?

0:15 somnium: so much more man, so much more

0:16 hiredman: ~laugh

0:16 clojurebot: ha ha

0:17 Licenser: somnium: does your driver support sorting?

0:17 somnium: I like clojure to be clojure and java to be the jvm, and the nasty 25 classes in one package interface didn't map well to the examples I found

0:17 Licenser: not yet, it seems it has be done with the cursor

0:17 Licenser: hmm there is a sort function at least in the console client

0:18 somnium: if the javadocs there's a skip and limit function defined for find

0:18 but its not found when I inspect the class

0:19 I'll wrap the cursor once I get this proxy business sorted, then skip, limit, sort etc. should be easy

0:19 try doing (clojure.contrib.repl-utils/show (.find some-collection))

0:19 hiredman: ,(set (map #(.getName %) (.getMethods String)))

0:19 clojurebot: #{"compareTo" "equalsIgnoreCase" "subSequence" "trim" "codePointBefore" "compareToIgnoreCase" "getClass" "isEmpty" "length" "getChars" "toCharArray" "valueOf" "charAt" "indexOf" "notify" "toString" "codePointCount" "replaceAll" "substring" "intern" "matches" "copyValueOf" "lastIndexOf" "replace" "concat" "wait" "getBytes" "toLowerCase" "codePointAt" "startsWith" "toUpperCase" "format" "contentEquals" "notifyAll" "offsetBy

0:24 hiredman: my reader is dog slow

0:27 somnium: can't you just copy the one from SICP?

0:28 hiredman: I am copying the one from LispReader.java

0:28 Licenser: well I just self sort ^^

0:28 somnium: does he do reader macros?

0:28 hiredman: I don't type hint anything

0:28 yeah, it's all reader macros

0:28 just not user extendable

0:29 somnium: has there been some opposition to a heredoc or a """ ?

0:29 it seems to keep resurfacing but never gets anywhere

0:29 hiredman: there is a read table, if a character like '(' is in the read table control is passed to the matching reader macro

0:30 somnium: I got close to doing a string rearrangment of parentheses to make clojure like ruby

0:30 it always screwed up when the nesting got deep

0:30 hiredman: :(

0:30 it?

0:31 somnium: it was more like, I wonder how hard this would be...

0:31 macros written with it even worked for simple things

0:32 it might attract some people, just to show flexible it can be without even reader macros, I was thinking

0:32 that was before clojure.walk, maybe I'll try again

0:33 I think I screwed myself with this proxy class, it won't let me override a superclass method

0:41 scottj: Is there a shortcut for doing something other than first argument with -> or is (-> "string" (#(str "prepend" %))) the way to do it?

0:43 hiredman: ,(doc ->>)

0:43 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

0:43 hiredman: ,(->> "foo" (format "prepend %s"))

0:43 clojurebot: "prepend foo"

0:48 scottj: hiredman: thanks

0:52 piccolino: Is it bad style to put a question mark at the end of a boolean variable? Is that for functions only?

0:52 hiredman: I do that

1:18 piccolino: Is there a way to write a linefeed character literal? I can't do \linefeed nor \lf, and gooling is coming up short for me...

1:29 Nevermind, found char.

1:37 Licenser: (doc defn)

1:37 clojurebot: "([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata"

1:37 Licenser: ,(doc defn-)

1:37 clojurebot: "([name & decls]); same as defn, yielding non-public def"

1:51 hiredman: ,\newline

1:51 clojurebot: \newline

1:52 hiredman: ,\return

1:52 clojurebot: \return

1:52 hiredman: ,(str \newline)

1:52 clojurebot: "\n"

1:52 hiredman: piccolino:

1:52 Raynes: hiredman: Don't you use Vim for Clojure development? (or do I just need to sleep more often?)

1:53 hiredman: I do

1:53 Raynes: I've decided to move away from Emacs for a while to see what all the fuss is about Vim.

1:54 I've been using it all day. I think I might keep using it.

1:54 It's a little easier to remember individual commands than it is to remember key patterns. ._.

1:55 hiredman: a vim habit is hard to break, I often hit <esc>:wq while writing emails in gmail

1:56 Licenser: hiredman: I have a few word documents with :wq lines :P

1:56 Raynes: :>

1:56 Once I figured out how to split panes in different directions and switch through buffers, I was a-go.

1:57 hiredman: I've noticed myself trying to use screen window switching commands in place of alt-tab

1:58 Licenser: yap that is bad

1:58 evern worst when you switch between mac and PC

1:58 hiredman: and irssi's channel switching stuff in place of screen's window switching

1:58 Licenser: especially the german keyboard

1:58 Raynes: I'm using GVim until I get used to Vim.

1:58 Licenser: the @ sign when typed wrongly will do horrible things

1:59 Raynes: GVim makes a Emacsist feel at home.

1:59 Licenser: if I use the widows key combo for @ on os X it will close a window, if I use the os x key combo on windows it will log me out ...

1:59 hiredman: Raynes: I have to warn you, vimscript is horrible

1:59 Raynes: hiredman: Huh?

1:59 hiredman: vim's scripting language

2:00 Raynes: I never did any custom Emacs scripting anyways.

2:00 I just googled what I needed if I needed something.

2:00 * Raynes is off to bed.

2:01 Licenser: night Raynes

2:20 what is the reason that there is no !=?

2:20 so everyone can has fun with cons?

2:23 arsatiki: huh?

2:23 Are you looking for not= perhaps?

2:24 Licenser: ,(doc not=)

2:24 clojurebot: "([x] [x y] [x y & more]); Same as (not (= obj1 obj2))"

2:24 Licenser: yap I'm looking for that :P

2:28 bradfordstephens: Whoa, there's people in here!

2:30 Licenser: bradfordstephens: and most of them even are helpfull is my experience :) clojure has a great community

2:30 bradfordstephens: I'm working through Paul Graham's book on Lisp now...my friend is one of "Those People" who kept insisting. So I gave in ;)

2:31 Licenser: heh

2:31 for me Clojure was the reason to bother with LISP

2:37 kylesmith: Are there any good genetic algorithm libraries in clojure? The first few hits on google don't look very appealing to me.

2:39 seangrove: require 'rubygems'

2:39 require 'sqlite3'

2:39 require 'activerecord'

2:39 # connect to database. This will create one if it doesn't exist

2:40 MY_DB_NAME = ".my.db"

2:40 MY_DB = SQLite3::Database.new(MY_DB_NAME)

2:40 # get active record set up

2:40 Licenser: seangrove: ?

2:40 seangrove: ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => MY_DB_NAME)

2:40 # create your AR class

2:40 class Update < ActiveRecord::Base

2:40 end

2:40 # do a quick pseudo migration. This should only get executed on the first run

2:40 if !Update.table_exists?

2:40 ActiveRecord::Base.connection.create_table(:updates) do |t|

2:40 t.column :account_name, :string

2:40 t.column :last_update_time, :timestamp

2:40 t.column :last_update_id, :integer

2:40 end

2:40 Sorry guys, emacs is going a bit wacky

2:40 I meant to paste that into a different buffer, but emacs reconnected to irc and started popping up irc channels

2:41 Licenser: :P

2:41 def my_companies_secret_code ...

2:41 seangrove: Hahaha

2:42 Licenser: hrm I hate the backtrace if it leaves out some function :/

2:44 uh

3:23 wooby: anyone a vimclojure user?

3:34 vy: What's the prefered way to swap two elements of a seq, particularly a vec?

3:38 arsatiki: Any two items or e.g. first two?

4:02 Fossi: hi

4:13 vy: arsatiki: Any two items.

4:22 Why Clojure complains that "clojure.lang.LazySeq cannot be cast to clojure.lang.IFn" for (let [{v :v} {:v (take 20 (iterate inc 0))}] (v 10))?

4:26 jdz: vy: because LazySeq does not implement IFn?

4:29 vy: jdz: What should I do to make (v 10) work?

4:29 jdz: vy: either use a vector or nth

4:29 piccolino: Is there some function I can call to allow multiple forms to be evaluated and return the last one?

4:30 Like progn?

4:32 jdz: piccolino: do

4:33 piccolino: Ah, there we go. Thank you.

4:38 wavis_: is there a way to do something like this:

4:38 (let [oldns *ns* throw-away (clojure.lang.Namespace.)] (in-ns throw-away) (foo) (in-ns oldns))

4:38 IE, avoid global state by sandboxing functions

4:39 jdz: wavis_: like (binding [*ns* (new clojure.lang.Namespace)] (foo))?

4:39 wavis_: binding requires declaring vars in the namespace first

4:39 ohh sorry...

4:40 i didn't know I could do that

4:41 right... so constructing a namespace is still a problem

4:41 jdz: wavis_: how about create-ns

4:41 ,(doc create-ns)

4:41 clojurebot: "([sym]); Create a new namespace named by the symbol if one doesn't already exist, returns it or the already-existing namespace of the same name."

4:42 wavis_: doesn't that leave the namespace lying around though, still resolvable?

4:43 jdz: wavis_: well, you have try/catch and remove-ns

4:43 wavis_: you'd actually want try/finally

4:45 wavis_: sounds kinda do-able, but the namespace would be global until removed, possibly creating a concurrency problem

4:45 jdz: ,(doc gensym)

4:45 clojurebot: "([] [prefix-string]); Returns a new symbol with a unique name. If a prefix string is supplied, the name is prefix# where # is some unique number. If prefix is not supplied, the prefix is 'G__'."

4:46 wavis_: good call

4:46 jdz: wavis_: or go and look at clojurebot source

4:46 it definitely has a sandboxing in there

4:46 wavis_: where is that?

4:47 jdz: like, google clojurebot?

4:47 wavis_: ok jdz. thanks

4:48 jdz: ,(+ 2 2)

4:48 clojurebot: 4

4:48 jdz: (+ 2 2)

4:48 clojurebot: 4

4:48 jdz: hmm

4:48 nvm

5:22 adityo: hey nipra :)

5:22 nipra: adityo, Hello!

5:23 adityo, wass up :-)

5:24 G0SUB: adityo, nipra

5:25 nipra: G0SUB, Hello!

5:25 AWizzArd: omg

5:25 ;)

5:26 adityo: ~max people

5:26 clojurebot: max people is 185

5:27 AWizzArd: wtf, it was 191 yesterday

5:28 clojurebot: max people is 191

5:28 clojurebot: Ack. Ack.

5:28 jdz: clojurebot: max people is 255

5:28 clojurebot: c'est bon!

5:28 jdz: make AWizzArd happy

5:28 AWizzArd: no, I'm going to cry, I want the real numbers

5:29 jdz: no, you're cheating

5:29 :)

5:29 Chousuke: clojurebot: forget max people

5:29 clojurebot: I forgot max people

5:29 Chousuke: ~max people

5:29 clojurebot: max people is 194

5:29 * AWizzArd sighs

5:29 Chousuke: I think it's a special function that just looks like a factoid. :)

5:29 and the definitions were overriding it

5:30 AWizzArd: I need to get my own bot in here.

5:32 I want to access my server S via https. On S a Jetty is running with a certificate that I created myself. Any ideas how I can make my jvm not throwing a SSLHandshakeException?

6:19 Jetien: hi! i have a general question. when i want to maintain a 2d state array, what is the better choice: 1. a vector of refs to vectors or 2. a vector of vectors of refs ?

6:21 or should i use some java data type?

6:21 Chousuke: are the states all independent of each other?

6:21 because the easiest option would be just to have a ref to a vector of vectors

6:25 a ref containing refs makes it difficult to have a consistent snapshot

6:26 Jetien: yeah they are very independent of each other

6:27 Chousuke: the vector of refs approach can be fine if the refs or their values don't depend on each other.

6:28 Jetien: hm what do you mean by depend? in my case there are just integers

6:28 s/there/they're

6:28 Chousuke: as in, to determine the value of one ref you need to read the others as well

6:28 in general, you should keep the granularity low at first and increase it if it becomes a bottleneck.

6:28 Jetien: ah i see, no not the case

6:29 Chousuke: coordinating many refs at once is difficult, and a vector of vectors of refs is really little better than a mutable 2d vector :/

6:29 Jetien: how does this approach perform anyway? is it not better just to use some java data type?

6:30 Chousuke: depends on what you need, I guess.

6:30 Jetien: hm huge in size like 1000x1000 with a lot of changes

6:30 Chousuke: with java data types Clojure can offer no assistance

6:31 hmm.

6:31 and it'll contain integers?

6:31 Jetien: but only one thread

6:31 yes

6:31 Chousuke: then I suppose having a million refs would be unacceptable overhead, memory wise.

6:32 Jetien: and time wise?

6:32 Chousuke: probably.

6:32 Jetien: hm okay

6:33 Chousuke: and if it's single-threaded there won't be much concurrent access to protect against.

6:34 so if you just use an array you'll only have to be careful not to depend on any previous value of the matrix

6:34 Jetien: i always wondered how a ref to vector performs if there are a lot of changes.. does the garbage collector clean up immediately?

6:34 Chousuke: it should be fine.

6:34 if your changes are done as a batch you can also use transients

6:35 Jetien: actually i never used concorrent programming ;) i'm all in for the lisp + java thing

6:35 let me google "transients"...

6:36 Chousuke: the array will likely perform best, but you will also not get all of the advantages immutability

6:36 ~transients

6:36 clojurebot: http://clojure.org/transients

6:37 Chousuke: basically a local mutable version of a persistent collection for making a lot of changes, with a fast operation for transforming it back into an immutable one again.

6:40 Jetien: ah that's nice...

6:40 i think that's what i'm looking for

6:41 wooby: Jetien: http://clj-me.cgrand.net/2009/10/15/multidim-arrays/

6:41 Jetien: thanks

6:41 wooby: no problem, i was trying to figure this out myself the other day

8:27 vy: What's the best way to model a matrix in a functional style in Clojure? Using a 1D vectors and mapping 2D coordinates to 1D coordinates via abstraction functions?

8:29 wooby: vy: i've done it that way, here's another: http://clj-me.cgrand.net/2009/10/15/multidim-arrays/

8:29 as to what's best, i don't know enough to know ;)

8:30 yason: vy: how large matrices? for what purpose?

8:32 vy: if you're doing simple 2D/3D stuff with your matrices, you could just use a vec of suitable length (like 6 entries for 2 x 3 matrix in 2D space) and use destructuring in defning the basic matrix ops since you pretty much know what you're going to add/multiply

8:33 vy: yason: I'll issue quite much col/row swap operations on a matrix collection of size ~100 where matrices are of size ~1000x1000.

8:33 yason: vy: that's a bit too much for destructuring :)

8:36 vy: [Disclaimer: I'm a beginner] You probably want speed too so you could consider make-array even though it's mutable. The functional approach would probably be to make the high-level functions pure -- even though you did mutations inside some matrix operation

8:37 octe: when running emacs slime with clojure i get "Lisp connection closed unexpectedly: connection broken by remote peer

8:37 "

8:37 used to work..

8:37 anyone have any clue what it could be?

8:38 yason: octe: slime/swank crashed?

8:38 octe: sync to the latest sources and see if it reproes

8:39 octe: yason: i sycned slime and swank-clojure to the latest

8:39 should i sync clojure too?

8:52 vy: In a `struct-map' call, Clojure complains that "clojure.lang.PersistentStructMap cannot be cast to clojure.lang.PersistentStructMap$Def", what could be causing this error?

8:56 arsatiki: vy: please post the code to a pastebin

8:59 chouser: vy: you need (struct-map foo ...) where foo is the name you gave in a (defstruct foo ...)

9:05 vy: arsatiki: chouser: Thanks. I think I figured out the problem.

9:25 yason: octe: IIRC there's a different swank/slime for Clojure 1.0 and trunk

9:25 octe: but if you're using the latest Clojure, then you probably should have latest slime/swank

9:53 chouser: huh. Proposal: Moratorium on Python language changes: http://lwn.net/Articles/357996/rss

9:54 "frequent changes to the language cause pain for implementors of alternate implementations"

10:03 cemerick: yeah, I saw that. The writing was on the wall years ago, tho.

10:03 chouser: 90% of the comments on lwn are negative.

10:05 cemerick: the ISO standardization notion at the end is *hilarious*

10:05 spuz: I don't understand that article. If you're changing python every month it doesn't imply that you need to change Jython every month does it?

10:06 chouser: I think it's interesting to consider Clojure's related position in light of cinc.

10:07 rhickey: chouser: in what way?

10:07 cemerick: spuz: I think that's a red herring. The language has been largely frozen for years, it's just been window dressing for some time.

10:07 spuz: chouser: why, how much is cinc going to affect users?

10:07 chouser: once cinc is done, the amount of work to create a Clojure host-port will be pretty small compared to the amount of work to create Jython

10:07 spuz: I see

10:08 chouser: and with that small creation work comes smaller maintenance work. It should be rather less effort to keep the ports in sync.

10:08 rhickey: the biggest difference is that a Lisp has so little in the language/compiler proper - most is libraries

10:09 chouser: many changes that would count as "grammar or language semantics" won't require any porting work at all

10:09 notallama: shouldn't pypy do that, too? you only need to implement the part for pypy requires.

10:09 chouser: right, because they're implemented in the core "library"

10:10 but even changes on the scale of "defclass" which are likely to be much rarer will still be largely discreet pieces and comparatively little effort, I think. Well, I hope anyway.

10:10 djork: indeed, it's pretty hard to make a "breaking change" to the syntax of a Lisp

10:10 notallama: i thought that was the entire point of pypy, actually: to make porting python easier.

10:11 cemerick: I thought it was an optimization and 'alternative feature' (e.g. continuations) playground.

10:11 djork: although Clojure's reader is more complex than any other Lisp I've seen

10:12 notallama: complex meaning it has 3 different kinds of brackets?

10:12 djork: well yeah, that and a lot of the reader dispatch macros

10:14 () [] {} #{} ' ^ @ # #"" #' #_ #() #^ ^# #^{} ` ~ ~@

10:14 but the read table is a nice implementation

10:15 I wish I could extend it

10:16 but maybe not :)

10:16 chouser: djork: you're not the only one to express interest. :-)

10:17 djork: I guess I shouldn't trust myself with the ability to add reader macros if I can't trust other people

10:21 arsatiki: djork: what does ^# do?

10:21 djork: oops maybe not that one

10:22 chouser: #^ is pretty much the same as #^{}

10:22 tmountain: is there a summary table online somewhere with all the reader macros in it?

10:23 chouser: tmountain: http://clojure.org/reader

10:24 notallama: how would user reader macros work with namespaces? presumably you'd want a way to use a namespace minus a reader macro.

10:25 * cemerick hides

10:25 chouser: notallama: that's similar to rhickey's main objection

10:25 * chouser wades right in

10:25 * cemerick can't bear to watch ;-)

10:26 chouser: I had a proposal to solve the namespace issue and address some percentage of reader macro use-cases, but I think it was seen as sort of a "worst of each" compromise.

10:28 djork: I think it could cause maintainability and readability issues to let people add custom reader macros. Regular macros are powerful enough.

10:28 it starts to look like Perl with too many of them

10:31 ambient: i wouldn't necessarily have a problem with encapsulated reader macroes that implemented a DSL

10:31 meaning, I would find that thing probably very useful

10:31 djork: probably

10:31 chouser: think xpath or a custom regex implementation

10:31 djork: granted pretty much anybody that is working with Clojure code is working on it by themseves

10:32 or how about XML-in-Clojure

10:32 like, literally XML

10:32 cemerick: oh, god, no

10:32 djork: :)

10:32 like Scala

10:32 cemerick: seriously, no.

10:32 * cemerick reaches for the Scotch

10:32 djork: I rest my case

10:32 vy: What's wrong with (defn distinct-rand-int-seq [n m] (first (remove #(apply = %) (repeat #(repeat m (rand-int n)))))) that Clojure complains that "Don't know how to create ISeq from: foo$rand_int_seq__2939$fn__2944"?

10:32 ambient: array slicing operations would be nice with reader macroes afaict, as little as I know about them

10:33 chouser: cemerick: but weren't you just calling for literal Java? you could do that with a reader hook

10:33 djork: inline Java?

10:33 interesting idea

10:33 chouser: ambient: I don't think a reader macro helps much there -- maybe slightly more terse than (slice x 4 5)

10:34 cemerick: chouser: Big difference between simplifying integration with the host language and choosing to elevate a particular data representation to a first-class entity.

10:34 chouser: cemerick: right, I'm just saying a reader hook allows both

10:35 cemerick: java-in-parens would surely require a reader mod, but I don't think that's an argument for a generalized hook.

10:35 chouser: vy: I'm not sure repeat does what you think it does.

10:35 djork: yeah

10:36 ambient: chouser i should look more into lisp implementation of Matlab or Numpy style array processing, but I don't believe that it would be so readable nor concise

10:36 djork: ,(repeat 10 (rand-int 10))

10:36 clojurebot: (2 2 2 2 2 2 2 2 2 2)

10:36 djork: ,(repeat 10 "hi")

10:36 clojurebot: ("hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi" "hi")

10:36 vy: hrm...

10:36 chouser: ,(repeat 3 #())

10:36 clojurebot: (#<sandbox$eval__3820$fn__3822 sandbox$eval__3820$fn__3822@1558d62> #<sandbox$eval__3820$fn__3822 sandbox$eval__3820$fn__3822@1558d62> #<sandbox$eval__3820$fn__3822 sandbox$eval__3820$fn__3822@1558d62>)

10:36 djork: hah

10:36 ,(take 10 (repeatedly #(rand-int 10)))

10:36 clojurebot: (2 5 9 0 4 0 3 3 9 6)

10:39 octe: ugh.. my slime setup still gives me "Lisp connection closed unexpectedly: connection broken by remote peer"

10:39 run latest of.. everything

10:39 anyone have any idea how to debug it?

10:42 vy: what does *inferior lisp* buffer tell?

10:43 octe: http://pastebin.ca/1645194

10:44 that's all

10:44 patricius_: would Clojure ever be able to be as 'efficient' as Erlang in terms of "process spawning"?

10:44 octe: http://pastebin.ca/1645195 <- slime-events

10:44 patricius_: I'm asking since Clojure uses 'real threads' as opposed to Erlangs 'green threads'

10:45 vy: octe: M-x slime-abort-connection M-- M-x slime clojure (when asks for an extra inferior lisp, say no.)

10:45 djork: patricius_: I think Clojure and Erlang have different priorities

10:46 patricius_: Clojure is better at balancing computation on multiple cores, Erlang is better at distributing computation across multiple servers

10:46 patricius_: djork: clojure is for parallelism and erlang for massive concurrency?

10:46 ambient: patricius_ the way I understood it, agents use 'green threads', but I haven't really studied or used them in depth

10:46 octe: patricius_: that seems to work

10:47 err

10:47 vy: that seems to work

10:47 doesn'

10:47 t hnmm

10:47 says Connected. Hack and be merry!

10:47 but doesn't give me a repl buffer

10:47 and sending soething to it gives an error

10:48 error in process filter: slime-dispatch-event: Elisp destructure-case failed: (:write-string "hi

10:48 ")

10:48 error in process filter: Elisp destructure-case failed: (:write-string "hi

10:48 ")

10:48 nil

10:49 lisppaste8: rhickey pasted "playing with defclass" at http://paste.lisp.org/display/89364

10:51 rhickey: still todo: Seqable, Counted, toString, Associative...

10:52 vy: octe: See http://paste.lisp.org/display/89365

11:03 djork: rhickey: how much work for defclass is "under the hood?"

11:03 looks like IObj and ILookup?

11:04 chouser: those are just interfaces

11:04 djork: oh right

11:05 rhickey: djork: not sure about your question, defclass and deftype build on defclass* which is a generic exposure of code generation capability that had been locked inside fn

11:05 djork: oh ok

11:05 octe: vy: still doesnt work, but now i get some errors when doing the connection with M- prefix

11:05 http://paste.lisp.org/display/89366

11:06 chouser: defclass* doesn't do closures though, right? so fn will still need compiler help?

11:07 ambient: to implement a repl in a swing window would i just have to read, eval, loop? :p

11:07 rhickey: chouser: there is a minor partitioning around closure, defclass* roots the environment at the field set, fn and newnew don't

11:07 newnew is still there and shares all of the benefits, like bridge generation

11:07 chouser: rhickey: ok. can they share gen code?

11:07 rhickey: oh yes

11:07 chouser: ah, fantastic.

11:08 ambient: yep. it's been done a couple times.

11:08 ambient: cool, thanks. i just thought that I was being blindsighted by something obvious :)

11:08 rhickey: when/if I expose volatile again it will likely be for defclass* only

11:09 chouser: this will be such a clean bytecode-gen api, I wonder if other languages will use it.

11:09 implement my-new-toy-language in clojure instead of java+asm

11:09 ambient: i'd think Forth was better for that ;)

11:27 gerry_: hello

11:28 Licenser: aloa

11:31 gerry_: i'm looking at hickey's paste code, (:d x 42) used for what?

11:33 djork: what's the best way to reload a lib from a repl?

11:34 oh :reload

11:37 chouser: gerry_: that's a ILookup by keyword :d, with 42 used as the "not found" value.

11:37 gerry_: it seems not work

11:37 chouser: I haven't tried it. what does it return?

11:38 gerry_: nil

11:38 chouser: hm.

11:39 gerry_: (:d x 42) return 42, but (:d x) return nil

11:40 chouser: oh, that's correct

11:40 :d doesn't exist in x, so (:d x) should return nil and (:d x foo) should return foo

11:41 gerry_: (defclass one [#^int a #^String b])

11:41 i got " Can't type hint a primitive local " error msg

11:43 chouser: you are right

11:43 headius: that's the defclass syntax?

11:43 what is #^ doing there?

11:44 chouser: headius: defclass barely exists yet. http://paste.lisp.org/display/89364

11:45 headius: the #^int a attaches metadata {:tag 'int} to the symbol a, which defclass then interprets as the type it should make field a to be.

11:46 headius: I see

11:46 is that a clojurism or a lisp thing (the #^ syntax)?

11:47 chouser: headius: I believe #^ is not in other lisps

11:50 gerry_: rhikey's paste code works here, good job, congr richkey!

11:51 stuartsierra: #^ is a Clojure reader macro to attach metadata to the *following* symbol or data structure

11:51 headius: ok

11:54 Licenser: muhaha I forked my first github project!

11:56 djork: congrasturbations

11:56 Licenser: thank you djork and it's even in clojure :P

11:57 djork: did you fork your own project or someone else's? :)

11:57 Licenser: I forked somnium mongodb driver

11:57 because I spend the day in airplains and took the time to fix some problems I had with it

11:57 or started to fix :P

11:57 so I figured why not try out how it works

12:53 yuras: i would like to change behavior of function accept-fn of contrib/server-socket. what is the idiomatic way to make it if i dont want to copy&paste whole server-socket server? is there a way?

12:55 Chousuke: ~def server-socket

12:55 clojurebot: excusez-moi

12:55 Chousuke: ;(

12:55 yuras: ~def create-server

12:57 Chousuke: hmmh

12:58 yuras: basically i want to make it passing socket object into function, i know i can rewrite it completely, but thinking about the better way. the thing that i need to know ip address of remote socket

12:59 Chousuke: I don't think there's a better way

12:59 fabe: hi beginners question: is their a sum function like in python ?

12:59 Chousuke: fabe: it's + :)

12:59 ,(apply + [1 2 3 4])

12:59 clojurebot: 10

12:59 fabe: (+ coll) ?

12:59 ambient: ,(reduce + [1 2 3])

12:59 clojurebot: 6

12:59 Chousuke: or that

12:59 fabe: k thx

13:00 arsatiki: is there a significant performance difference either way?

13:00 oh wait, I have a repl. I can check for myself.

13:00 Chousuke: well, + uses reduce internally

13:00 ambient: such micro-optimazion likely has no value

13:00 Chousuke: yeah

13:01 often, apply is better though.

13:01 for example, (apply str '[foo bar whatever]) is faster than (reduce str '[foo bar whatever])

13:03 arsatiki: yeah. no value whatsover =)

13:03 Chousuke: str uses a stringbuilder internally in the apply case, but using reduce will force it to create temporary strings

13:03 tmountain: on my box, reduce is faster in this case (not that it matters much)

13:03 (time (reduce + (range 1 10000000))) "Elapsed time: 804.801736 msecs"

13:03 (time (apply + (range 1 10000000))) "Elapsed time: 3275.64601 msecs"

13:04 hiredman: that is +

13:04 Chousuke: hmm, that might actually be because of chunked seqs

13:04 hiredman: Chousuke is talking about str

13:04 Chousuke: perhaps using apply will lose the chunkiness information of range, so the reduce in + can't take advantage of it

13:05 tmountain: I need to read up on chunked sequences

13:05 so many new concepts coming down the pipe that it's hard to keep up ;-)

13:06 ambient: i thought the chunkiness was mostly automatic, at least I haven't had to burden my brain with it

13:06 at least I shouldn't ought to

13:06 Chousuke: (letfn [(foo [a b & therest]] (chunked-seq? therest))] [(apply foo (range 1000)) (chunked-seq? (range 1000)])

13:06 .,(letfn [(foo [a b & therest]] (chunked-seq? therest))] [(apply foo (range 1000)) (chunked-seq? (range 1000)])

13:06 ,(letfn [(foo [a b & therest]] (chunked-seq? therest))] [(apply foo (range 1000)) (chunked-seq? (range 1000)])

13:06 clojurebot: Unmatched delimiter: ]

13:06 arsatiki: tmountain: fascinating. I can't reproduce that at all (I get 800 +- 20 msec with both)

13:06 Chousuke: :P

13:06 hm

13:06 ambient: haha :D

13:06 Chousuke: gah

13:06 ,(letfn [(foo [a b & therest] (chunked-seq? therest))] [(apply foo (range 1000)) (chunked-seq? (range 1000)])

13:06 clojurebot: Unmatched delimiter: ]

13:07 arsatiki: tmountain: do you have a cutting edge clj perhaps?

13:07 Chousuke: ...

13:07 tmountain: Clojure 1.1.0-alpha-SNAPSHOT

13:07 Chousuke: ,(letfn [(foo [a b & therest] (chunked-seq? therest))] [(apply foo (range 1000)) (chunked-seq? (range 1000))])

13:07 clojurebot: [true false]

13:07 Chousuke: huh

13:07 interesting.

13:08 I would have expected the opposite

13:08 arsatiki: tmountain: right. I have 1.0.0

13:09 chouser: ,(chunked-seq? (seq (range 1000)))

13:09 Chousuke: ,(time (reduce + (range 1000000)))

13:09 clojurebot: 499999500000

13:09 "Elapsed time: 771.331 msecs"

13:09 true

13:09 Chousuke: ,(time (apply + (range 1000000)))

13:09 clojurebot: 499999500000

13:09 "Elapsed time: 1472.001 msecs"

13:09 arsatiki: huh

13:09 tmountain: I'm guessing clojurebot is bleeding edge?

13:09 Chousuke: ,(time (reduce str (range 10000)))

13:09 clojurebot: "0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177

13:10 "Elapsed time: 1562.735 msecs"

13:10 Chousuke: ,(time (apply str (range 10000)))

13:10 clojurebot: "0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177

13:10 "Elapsed time: 30.616 msecs"

13:10 Chousuke: funky, huh :P

13:10 tmountain: wow

13:10 arsatiki: yeah

13:10 ambient: the basics of string concatenation

13:10 Chousuke: in the str case it's obvious why apply is so much faster, but the + case is surprising

13:11 hiredman: clojurebot: clojurebot is not a benchmarking platform

13:11 clojurebot: c'est bon!

13:11 ambient: reduce is (f (f (f (f str)))) apply is (join str-a str-b str-c)

13:12 Chousuke: ambient: the (f (f (f ...))) one is iterate though. :) reduce is (f str3 (f str2 (f str1 init)))

13:13 though the parameter order is the other way around :P

13:13 hiredman: ,(time (reduce #(.append %1 %2) (StringBuilder.) (range 10000)))

13:13 clojurebot: #<StringBuilder 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172

13:13 "Elapsed time: 1415.392 msecs"

13:14 Chousuke: ,(time (reduce #(.append #^StringBuilder %1 %2) (StringBuilder.) (range 10000)))

13:14 clojurebot: #<StringBuilder 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172

13:14 "Elapsed time: 9.241 msecs"

13:14 hiredman: zounds

13:14 Chousuke: avoiding reflection = important

13:14 ambient: Chousuke yes, but i was trying to illuminate the fact that reduce is recursive and apply iterative, at least in this case, AFAIK

13:14 hmm, or is iterative the word im looking for

13:14 hiredman: erm

13:15 reduce is iteriation implimented via recur

13:15 ambient: the point is that reduce does string=string+stuff at each step and apply does string=a+b+c+d+e+f

13:16 hiredman: ambient: but str has to use a loop that is just like reduce internally to process all the args

13:17 ambient: str can do (let [new-string-len (+ (length a) (length b) (length c))] ...)

13:18 fabe: wow getting your head around functional programming is harder then i thought took me an hour to to write my first small programm :)

13:18 ambient: whereas string=string+stuff doesn't know the final result and thus has to do O(n) operation at each step of iteration

13:18 hiredman: ambient: no, it can't

13:18 strings are immutable

13:19 ambient: well then, create a new string which is the old string plus some other stuff. same diff

13:19 hiredman: so you can't just declare a string of length n and fill it in, and you would still have to use a reduce-ish looking loop

13:19 ambient: i see

13:20 but clojure strings are java strings, i read that somewhere

13:20 hiredman: and java strings are immutable

13:20 ambient: so perhaps the innards are still mutable

13:20 hiredman: nope

13:20 arsatiki: I tried to do a faster integer sum with type hits but ran into a snag. How do I tag primitive types?

13:20 chouser: The difference is StringBuilder is mutable and so can cheat

13:21 arsatiki: Using #^int says "Unable to resolve classname"

13:21 chouser: (apply str ...) uses a StringBuilder internally where (reduce str ...) can't

13:21 hiredman: ~performance

13:21 clojurebot: http://clojure.org/java_interop#toc46

13:22 hiredman: arsatiki: that's for you

13:23 chouser: hiredman: have you considered a way to tell clojurebot to direct an answer at someone? don't know what the syntax would be.

13:23 rhickey: deftype is alive!

13:23 arsatiki: hired: tnx. Turns out that was a bad idea :)

13:24 hiredman: clojurebot: tell so and so about something

13:24 clojurebot: Gabh mo leithscéal?

13:25 chouser: rhickey: so cool. I won't have a chance to port finger trees for a couple days, but I'm looking forward to it. Should be a great fit.

13:26 rhickey: ought to be able to use 'new' to implement defclass interfaces until protocols are ready? or am I jumping the gun?

13:27 rhickey: chouser: I'm not sure what about what you;ve already done would have to change

13:28 chouser: gen-interface stays for now?

13:28 rhickey: but generally, yes, you can always wrap an interface in a protocol

13:28 I'd like a definterface that matches deftype/defclass syntactically

13:28 but same plumbing as gen-interface

13:28 chouser: yeah, ok.

13:29 so right now each node and digit data is stored in a newnew closure

13:29 with hand-written accessors as needed

13:29 moving that to deftype would be a win I think

13:30 rhickey: accessors used outside the node?

13:32 chouser: used by other instances of the same class, yes.

13:33 specifically, the pre/mid/suf triplet that makes up a deep-node.

13:33 rhickey: ok, so with defclass you can get .field access to other instances of same type, with deftype only :field access

13:33 in either case no manual accessors needed

13:34 (defclass gives you :field as well)

13:34 chouser: right. so deftype's dynamism would have been lovely during development, but now I'd probably go straight to defclass

13:35 rhickey: that's the idea, although for many use cases you;d never need to go to defclass, swapping defclass for deftype and . for : is a breeze

13:35 chouser: right, I've already crossed an ugly line or two trying to wring performance out of finger trees, so defclass for me.

13:36 * rhickey setting up smack-down between deftype and defstruct

13:36 chouser: the one area I haven't worked on performance is the measure/reduce stuff, but I have a vague notion that deftype/defclass may be great there too.

13:37 right now, users pass in a map of vectors of fns: {:size [(constantly 1) + 0] :str [str str ""]}

13:38 well, two fns and a seed value

13:38 but it probably ought to be either a map or a plain list of instances that implement IMeasureReduce or something

13:39 hm, except I don't know the types involved, and primitives would be really nice is I could find a good way to store them...

13:49 leafw: is there any way to pretty-print maps of maps with indentation?

13:49 chouser: leafw: clojure.contrib.pprint

13:50 Chousuke: contrib has a pretty-printer. maybe you can use that?

13:50 Raynes: How would I filter through a sequence, removing every other element of the sequence?

13:50 chouser: ,(partition 2 1 (range 10))

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

13:50 leafw: chouser, Chousuke: I called (pprint {:a 1 :b 2 :c {:f 11 :g 44} :r 34}) and printed all in one line.

13:50 chouser: ,(partition 1 2 (range 10))

13:50 clojurebot: ((0) (2) (4) (6) (8))

13:50 chouser: ,(map first )(partition 1 2 (range 10))

13:50 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$map

13:50 leafw: I am trying to figure out where are the docs

13:50 chouser: ,(map first (partition 1 2 (range 10)))

13:50 leafw: there may be options.

13:50 clojurebot: (0 2 4 6 8)

13:51 Raynes: Thanks.

13:51 Chousuke: leafw: contrib documentation is on github

13:51 linked in the wiki

13:52 http://richhickey.github.com/clojure-contrib/pprint-api.html here. :)

13:53 leafw: thanks.

13:55 woah, pprint doesn't indent by default and the docs are just ... way too low level

13:57 so, despite all the effort put by the author, I find pprint useless. Dead-brain examples would be nice.

13:59 hiredman: ,(doc *pretty-print*)

13:59 clojurebot: No entiendo

13:59 chouser: try pprinting a bigger map.

13:59 hiredman: uselesss

13:59 chouser: I'm pretty sure it's done a nice job intedenting without any special options for me.

13:59 hiredman: ~def *pretty-print*

13:59 clojurebot: I don't understand.

13:59 leafw: hiredman: (doc pprint)

14:00 hiredman: leafw: *pretty-print* is one of pprint's tuning vars

14:00 the docs say bind to true if you want pretty printing

14:00 but the source reveals that it defaults to true

14:01 maybe play around with miser-width

14:02 leafw: hiredman: I read the pprint_base.clj code and I I saw that too: all one can do is limit the width.

14:04 hiredman: ,(take-nth (range 10) 2)

14:04 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

14:04 hiredman: bah

14:04 ,(take-nth 2 (range 10))

14:04 clojurebot: (0 2 4 6 8)

14:07 leafw: to concat two vectors? I keep forgetting this simple things

14:07 it's not conj, neither conc or concat

14:07 Chousuke: (into vec1 vec2) works

14:08 leafw: into ... reads like misusing it, but thnaks

14:08 Chousuke: not really :)

14:51 yuras: how to make hash map from sequence? like (a 2 b 4) -> {a 2, b 4}

14:53 leafw: yuras: a combination of zipmap and interleave ... it can be done.

14:55 chouser: ,(apply hash-map

14:55 clojurebot: EOF while reading

14:55 chouser: ,(apply hash-map '(a 2 b 4))

14:55 clojurebot: {a 2, b 4}

14:56 leafw: there, eev easier.

14:56 yuras: oh, blame me

14:59 speaking of shortest ways. i made transformation of ((1 2) (3 4)) -> {1 2, 3 4}

14:59 this way

14:59 (apply hash-map (reduce concat '((1 2) (3 4))))

14:59 is that the shortest one? :)

15:00 ,(apply hash-map (reduce concat '((1 2) (3 4))))

15:00 clojurebot: {1 2, 3 4}

15:01 chouser: ,(into {} '((1 2) (3 4)))

15:01 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Map$Entry

15:02 chouser: ,(into {} '([1 2] [3 4]))

15:02 clojurebot: {1 2, 3 4}

15:02 chouser: ,(into {} [[1 2] [3 4]])

15:02 clojurebot: {1 2, 3 4}

15:02 chouser: yuras: the inner things must be lists and not vectors?

15:02 yuras: that what re-split returns

15:03 chouser: ,(into {} (map vector '((1 2) (3 4))))

15:03 clojurebot: java.lang.IllegalArgumentException: Vector arg to map conj must be a pair

15:03 chouser: ,(into {} (map vec '((1 2) (3 4))))

15:03 clojurebot: {1 2, 3 4}

15:03 yuras: oh man, you are wizard

15:04 chouser: AWizzArd: <-- no he's the wizard apparently. :-)

15:06 djork: into is magic

15:09 yuras: yeah, digging the sources

15:10 is there a way to peek sources of function from repl?

15:11 djork: I dunno but it's a nice idea.

15:12 yuras: cheat sheet contains source as doc fun, but its not resolved in 1.1 snapshot

15:13 djork: ,^#'into

15:13 clojurebot: {:ns #<Namespace clojure.core>, :name into, :file "clojure/core.clj", :line 4561, :arglists ([to from]), :doc "Returns a new coll consisting of to-coll with all of the items of\n from-coll conjoined."}

15:13 djork: oh god it's perl

15:13 so there you get the file and line

15:13 and you can go from there probably

15:13 leafw: suppose I have an input stream with clojure code to evaluate. What is the best way to do it? Perhaps load-reader ?

15:14 yuras: oh. (source x) is in (use 'clojure.contrib.repl-utils) !

15:14 djork: yay, I thought it might be

15:14 yuras: ,(source into)

15:14 clojurebot: Source not found

15:15 djork: aw

15:15 clojure src must not be in the classpath for the bot

15:16 maybe it could be if we ask nicely?

15:17 yuras: ~def into

15:18 i guess its like that and no more

15:19 djork: is it just me or is into not tail-recursive?

15:19 could it blow the stack with a big enough from?

15:19 chouser: 'recur' is illegal outside a tail position

15:19 djork: oh ok

15:19 I must not understand tail position

15:19 chouser: yet another reason to love it

15:20 djork: if you have (if foo bar), foo is in tail position?

15:21 chouser: yes

15:21 no

15:21 yuras: its not

15:21 chouser: (if test then else)

15:21 test is not in tail position, but then and else are

15:23 yuras: even after python, clojure operations on data look like huge boost, so many and so powerfull

15:23 djork: err yeah that's what I meant

15:23 (if test foo bar) foo is in tail position

15:23 chouser: djork: yes

15:24 djork: (if test (bar (foo)) bat) foo is not in tail position

15:24 chouser: correct

15:25 (if test bar (bat (foo))) foo is still not in tail position, even though it's "last"

15:26 djork: right

15:26 yuras: b/c foo is applied earlier than bat?

15:26 djork: because it's the *returning* call that is in tail position

15:26 and there can be many tail positions

15:26 chouser: yes

15:26 djork: OK that clicks now!

15:27 I never made the connection between tail call and returning

15:27 * djork didn't go to no fancy dance school

15:28 chouser: (do x y z tail) (if x tail tail) (let [a b c d] x y z tail)

15:28 hiredman: well, let is do + bindings

15:28 chouser: (fn [a c] x y z tail) (loop [a b c d] x y z tail)

15:29 hiredman: ,(lett [x 1 y 2] (+ x y))

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

15:29 chouser: (cond a tail b tail c tail)

15:32 hiredman: ,(lett [x 1 y 2] (+ x y))

15:32 clojurebot: 3

15:32 hiredman: ,(macroexpand-1 '(lett [x 1 y 2] (+ x y)))

15:32 clojurebot: ((clojure.core/fn [x] (sandbox/lett [y 2] (+ x y))) 1)

15:33 hiredman: explodes if you try to recur across it, which the real let doesn't

15:46 tomoj: how do you name your structmaps?

15:46 chouser: what's the best possible stack trace behavior for macro expansions?

15:46 tomoj: I find I want to call my local variables the same thing I used as the name of the structmap

15:47 hiredman: I like <foo> with foo being the name of the factory function

15:47 tomoj: wow, I hadn't realized <foo> was valid, nice

15:48 hiredman: it might not be technically, but it works

15:48 chouser: I suppose a sort of nested stack? Where you could see the filename and line number of each level of the macro expansion?

15:48 i think that would be desirable. is it possible?

15:49 hiredman: hmmm

15:49 tomoj: with my structs named <foo> I don't have to use silly local variables like my-foo or the-foo :D

15:50 hiredman: I think according to http://clojure.org/reader <foo> is not technically legal

15:50 somnium: tomoj: what's wrong with f? :)

15:50 tomoj: huh

15:50 hiredman: ,'!foo!

15:50 clojurebot: !foo!

15:50 tomoj: I wonder why it works, then

15:50 hiredman: ,'|foo|

15:50 tomoj: ,'<foo>

15:50 clojurebot: |foo|

15:50 <foo>

15:50 chouser: much is permitted that is not supported

15:51 hiredman: tomoj: the actually implementation is very lax in what it allows

15:51 :/

15:51 tomoj: well I like <foo>. easy to search/replace if it stops working someday.

15:51 hiredman: hmmm, |foo| is not legal either

15:51 -foo-

15:51 chouser: you could use Foo

15:51 hiredman: ,-foo-

15:51 clojurebot: java.lang.Exception: Unable to resolve symbol: -foo- in this context

15:52 somnium: ,(let [&$!# '<foo>] &$!#)

15:52 clojurebot: <foo>

15:52 hiredman: :P

15:52 clojurebot: much is permittted

15:52 clojurebot: Roger.

15:52 somnium: really, I don't get why the perl community isn't all over clojure

15:53 arbscht: somnium: &$!# that.

15:53 somnium: :)

15:54 tomoj: I hate uppercase

15:56 yuras: ,(into {} (for [[k v] '((1 2) (3 4))] [k v]))

15:56 clojurebot: {1 2, 3 4}

15:56 yuras: ,(into {} (for [[k v] '((1 2) (3 4))] [(keyword k) v]))

15:56 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: No matching method found: intern

15:56 hiredman: keyword takes a string

15:57 yuras: arhg

15:57 thanks

16:06 somnium: does this do copy-on-write: PersistentHashMap.create(new java.util.HashMap()); ?

16:06 Chousuke: probably not.

16:06 somnium: hmm

16:06 chouser: how could it?

16:07 somnium: presumably there's something in the map

16:07 chouser: java.util.HashMap could change and PHM wouldn't know

16:09 but anyway, no. it uses temporary transients to build a PHM copy of the juHM at the moment the PHM is created.

16:09 Chousuke: temporary transients :)

16:10 somnium: what about: PersistentHashMap.create(some-mutable-java-map-from-the-db-with-mutable-stuff-in-it);

16:10 chouser: Chousuke: yeah, maybe that was a bit unnecessary. :-)

16:11 If you've got a non-temporary transient you're already in trouble

16:11 somnium: PersistentHashMap.create doesn't do anything deep, so you'd get a PHM of mutable things.

16:12 somnium: ok, thanks

16:12 chouser: ,(let [m {:a (into-array [1])}] (aset (:a m) 0 99) (-> m :a first))

16:13 clojurebot: 99

16:16 somnium: is there anything like an into-with (a la merge-with) in core or contrib?

16:19 chouser: what would it do?

16:20 hiredman: sounds like reduce

16:20 ,(reduce conj #{} '(a b a c d g g w))

16:20 clojurebot: #{w a c b g d}

16:20 somnium: it does, doesn't it

16:21 chouser: ,(into #{} '(a b a c d g g w))

16:21 clojurebot: #{w a c b g d}

16:21 chouser: I still don't get it.

16:22 somnium: I was thinking [ x y & fs] (let [f (apply comp fs)] ... (conj x (f y)))

16:22 hiredman: chouser: yes, but with reduce you can specify to the function

16:22 that's called map

16:23 ,(into #{} (map inc (range 10)))

16:23 clojurebot: #{1 2 3 4 5 6 7 8 9 10}

16:23 somnium: into isn't lazy

16:24 hiredman: correct

16:24 djork: I think I want to implement a slideshow lib. Would that fit in contrib?

16:24 chouser: nothing that returns a vector can be lazy

16:24 djork: Or is that too high level?

16:24 hiredman: the only that is lazy are seqs, into produces things that arn't seqs

16:24 somnium: map is lazy

16:24 so it wouldn't be exactly the same, or I am I confused?

16:24 djork: PLT Scheme has the Slideshow language. Clojure could do the same thing.

16:25 Chousuke: what does that do?

16:25 djork: Chousuke: you mean Slideshow?

16:25 Chousuke: yes

16:26 djork: it lets you define slideshow presentations (think Powerpoint) in Scheme

16:26 hiredman: somnium: map returns a seq

16:26 always

16:26 seqs can be lazy, so map is lazy

16:26 somnium: (source map)

16:27 hiredman: ~def map

16:27 somnium: ~def into

16:27 hiredman: I already told you the difference

16:28 Sequences are the only non-explicitly lazy thing in clojure

16:28 map returns a sequence, into returns whatever type of collection you prime the pump with

16:29 ,(into {} '([a b] [c d]))

16:29 clojurebot: {a b, c d}

16:32 chouser: I can never ever remember which arg comes first for 'with-meta'

16:33 Hm, the opposite order that #^ uses. Maybe that'll stick this time.

16:35 arsatiki: here's my mnemonic: with-meta consists of two words, the latter of which is meta. it takes two arguments, the latter of which is meta.

16:35 hiredman: chouser: just think of it as a call to the .withMeta method

16:35 chouser: arsatiki: ok! thanks guys, maybe next time I can avoid running 'doc' again.

16:36 danlei: just use emacs

16:37 djork: heh, yes, slime solves all of my argument-order woes

16:37 tomoj: except for struct

16:39 chouser: emacs has already caused me more pain than any piece of software has the right to.

16:39 somnium: :)

16:40 chouser: then again, so has a bunch of software I still use, so I guess I should quit whining.

16:40 danlei: yes, it did that to me, too. but it also gave me more pleasure than any other :)

16:40 djork: I picked up Emacs to cut down on pain.

16:40 Editing Lua on Windows.

16:40 With no other significant tools.

16:41 danlei: when emacs is set up, everything is fine. it's just that it takes a lifetime :)

16:41 hiredman: lua is a neat little language

16:41 I love that the lua build process doesn't involve autotools

16:45 djork: Lua is truly lovely. The function environment features is really cool. Clojure could use something like it for sandboxing.

16:45 but it goes a bit too far for clojure, probably

16:46 woah, paged things in github have vim shortcuts

16:46 hiredman: my mp3 player has a lua interpreter

16:50 djork: a lot of things do... it's like sqlite

16:51 chouser: ooh, are there lua bindings for sqlite?

16:51 hiredman: there must be

16:51 chouser: gah, what am I saying. I retract the question.

16:52 leafw: xD

16:52 hiredman: http://github.com/hiredman/odds-and-ends/blob/master/lisp.lua

16:52 chouser: clojure is great for embedding in existing Java apps to make them scriptable, dynamic, whatever. We just need a version that will do the same for C-based apps.

16:53 hiredman: I'm pretty sure I never finished the interpreter

16:53 tmountain: chouser: won't that be a real possibility once clojure in clojure is done?

16:53 chouser: tmountain: maybe, but there would still be real engineering work to do.

16:54 leafw: is there any simple way to take two maps and return the common keys?

16:54 chouser: leafw: ignoring the values?

16:54 leafw: short of #{(keys m1) (keys m2)}

16:54 yes

16:54 just the keys

16:54 that wouldn't work ...

16:55 (into (keys m1) (keys m2)) perhaps

16:55 chouser: leafw: that gets you both

16:55 (filter #(contains? m1 %) (keys m2))

16:55 hiredman: leafw: look at clojure.set

16:55 or

16:56 chouser: ,(filter #(contains? {:a 1 :b 2} %) (keys {:b 3 :c 4}))

16:56 clojurebot: (:b)

16:56 leafw: thanks :)

16:56 hiredman: ,(doc clojure.set/intersection)

16:56 clojurebot: "([s1] [s1 s2] [s1 s2 & sets]); Return a set that is the intersection of the input sets"

16:56 leafw: probably clojure.set would have an intersection

16:56 there, thanks

16:57 hiredman: http://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj started pulling stuff out into macros

16:57 chouser: but you'd have to make a set from the maps which would be inefficient.

16:57 hiredman: ,(.keySet {:a 1})

16:57 clojurebot: #< [:a]>

16:58 hiredman: and most clojure.set functions just call seq on the sets anyway :(

16:59 leafw: chouser: I am not concerned about efficiency right now, thanks.

17:17 I am getting an error trace that makes no sense: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IObj (identify.clj:1

17:18 ... where at identify.clj:1 there is only a commented out line

17:18 no other lines of the exception stack trace refer to the file itself.

17:18 kotarak: leafw: you call meta somewhere on a string

17:19 ... maybe by passing a string to something expecting a symbol.

17:19 leafw: thanks kotarak -- checking

17:22 kotarak: you are right. In a defn, I had the string before the fn name.

17:22 the doc string, that is.

17:22 I would have never guessed so from the Exception stack trace.

17:22 kotarak: leafw: IObj is the meta interface

17:23 chouser: that's a compile-time exception which often has to be read a little differently

17:24 the final exception which is usually listed first (not the root cause, listed last) should have a file name and line number in the message itself

17:24 java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IObj (<filename>:<line number>)

17:25 kotarak: chouser: which, as leafw wrote above, is not always the correct spot... ;P

17:25 chouser: oh

17:25 you're right

17:25 hmph

17:26 leafw: was the bad defn in identify.clj?

17:26 leafw: same for missing [] for the arguments of a fn that takes no arguments: the stack trace points to the right line, but that's all the help it provides.

17:26 chouser: was the message cut off at :1 or was there a close paren there?

17:26 leafw: chouser: yes

17:26 at :1 there was a comment.

17:27 chouser: well, pointing to the right line can be a huge help.

17:27 leafw: was there a close paren after (identify.clj:1 ?

17:28 leafw: chouser: yes, my bad copy/paster.

17:28 chouser: hmph.

17:28 when I tried it just now I got the correct line number. I wonder what's different about your case.

17:28 dakrone: hey everyone, can someone help me understand how to get (str-utils2/replace "1d6" #"(\d+)d(\d+)" #"\1") to work with replacing regex groups?

17:28 leafw: try it: create a file with (defn "bla bla" fn-name-here [] (printl "hello"))

17:29 I have no idea :)

17:29 chouser: leafw: yeah, I did that, but it pointed me at exactly the right line.

17:29 kotarak: OT: Is there a Windows/VimClojure user around?

17:30 hiredman: dakrone: I kind of doubt replace takes two regexs

17:30 ,(require '[clojure.contrib.str-utils2 :as s2])

17:30 clojurebot: nil

17:30 dakrone: hiredman: according to the docs the replacement is allowed to be a pattern

17:30 hiredman: (doc s2/replace)

17:30 clojurebot: "([string pattern replacement]); Replaces all instances of pattern in string with replacement. Allowed argument types for pattern and replacement are: 1. String and String 2. Character and Character 3. regex Pattern and String (Uses java.util.regex.Matcher.replaceAll) 4. regex Pattern and function (Calls function with re-groups of each match, uses return value as replacement.)"

17:31 chouser: dakrone: (str-utils2/replace "1d6" #"(\d+)d(\d+)" "\\1x\\2")

17:31 kotarak: clojurebot: regex

17:31 hiredman: dakrone: [regex regex] is not listed as an allowed pattern

17:31 clojurebot: Sometimes people have a problem, and decide to solve it with regular expressions. Now they have two problems.

17:31 chouser: that double-escaping on replace is gross, but I don't know what would be better

17:32 dakrone: hiredman: okay, I read it wrong, I need to use a function then?

17:32 hiredman: chouser: are you sure that is right?

17:32 chouser: hiredman: worked here

17:32 hiredman: ok

17:32 chouser: or this, but it might get you in more trouble later: (str-utils2/replace "1d6" #"(\d+)d(\d+)" (str #"\1x\2"))

17:32 dakrone: (replace "foo" #"(\d)" (fn [g] g)) would work then?

17:32 hiredman: generally java uses $1 $2 for groups instead of \1 and \2

17:32 chouser: oh!

17:32 kotarak: ,(s2/replace "1d6" #"(\d+)d(\d+\)" "\\1x\\2")

17:32 clojurebot: Unclosed group near index 12 (\d+)d(\d+\) ^

17:32 chouser: yeah, do that: (str-utils2/replace "1d6" #"(\d+)d(\d+)" "$1x$2")

17:33 kotarak: ,(s2/replace "1d6" #"(\d+)d(\d+)" "$1x$2")

17:33 clojurebot: "1x6"

17:33 leafw: I have an autogenerated .clj file with 350000 lines, describing a map. And it fails to load. This map was pprint from an actual clojure map. Is there an internal limit to how big a clojure file can be to be loaded?

17:33 dakrone: kotarak: awesome, that works

17:33 thank you very much

17:33 kotarak: dakrone: well, that's just what chouser said. :)

17:34 leafw: what is the error you get?

17:34 leafw: kotarak: let me paste it somwehere

17:34 hiredman: the reader (written in java) has recursive calls to read, so at somepoint you will blow the stack

17:35 lisppaste8: leafw pasted "error loading gigantic .clj file with a map in it" at http://paste.lisp.org/display/89392

17:36 leafw: hiredman: the map is not very deep, only 4 or 5 levels max

17:36 i.e. map of maps etc.

17:37 hiredman: leafw: does it contain references to lineage/identify$eval__224

17:37 ?

17:38 leafw: not that I know of

17:38 the map should be plain data

17:38 no functions

17:38 hiredman: well, uh, can you grep it?

17:39 leafw: there is no "identify" neither "defn" neither "lineage" in it

17:39 hiredman: well, certain things like various reader macros can cause the reader to try and interpret something as a classname

17:39 leafw: there are String literals like this: "BLD6 [lineage] #550"

17:39 hiredman: are you sure the output is well formed?

17:40 leafw: AFAIK, whatever is inside the "" ought to be ignored

17:40 hiredman: yes

17:40 leafw: I can't be sure, was geenrated from pprint

17:40 but ok, I'll grep some more

17:40 hiredman: well just dump a subset of your data through pprint

17:41 is there a reason you are using pprint? if you aren't going to personally read the file, why bother pretty printing

17:41 leafw: vim via vimclojure colors it all correctly, that's a good sign.

17:41 hiredman: :(

17:41 kotarak: :)

17:41 leafw: hiredman: the reason was that I have to go through it a bit to see that its printing the right thing.

17:41 hiredman: leafw: can you replicate the whole thing outside of vimclojure?

17:42 leafw: hiredman: you mean running it standalone, not through nailgun? Sure, that is eactly what I did.

17:42 I am using latest master. Perhaps I should fall back to clojure 1.0

17:42 spuz: does clojure have functions for getting data over http? Ie. making a call to a webservice API?

17:43 kotarak: *pfew* *wishingsweataway*

17:43 hiredman: spuz: java.net.*

17:43 bradford: what is the best way to send a fn across process boundaries and get the correct interned var on the other side?

17:43 hiredman: bradford: magic pixie dust

17:43 bradford: argh!

17:44 I'm playing with lots of symbol, var and ns stuff

17:44 leafw: what a show stoppe.

17:44 kotarak: bradford: (let [the-val *var*] (fn [foo] (binding [*var* the-val] ...)))

17:44 spuz: hiredman: URL.openStream?

17:44 jdz: well, a function is just an instance

17:44 bradford: spuz: loot at contrib.http

17:44 leafw: hiredman: I'll try printing without pprint

17:44 kotarak: bradford: or the yet-to-be-included bound-fn macro

17:44 jdz: and instances can be serialised/deserialised, right?

17:45 bradford: kotarak: what the hell is that? :-)

17:45 hiredman: fns and vars are completely different

17:45 bradford: (let [the-val *var*] (fn [foo] (binding [*var* the-val]

17:45 ...)))

17:45 kotarak: bradford: that's the magix pixie dust

17:45 hiredman: vars are just storage

17:46 spuz: sure

17:46 jdz: a fn can close over data

17:46 jdz: hiredman: and how does that not make it an instance?

17:47 hiredman: jdz: it doesn't

17:47 bradford: aren't fns just using vars as part of namespace resolution? symbol name represents fn instance, which is bound to the var in the slot in teh global namespace map that is identified by the namespace/symbol combo?

17:47 kotarak: bradford: say you need *out* bound to something special in function foo in another thread. Then you do (let [saved-out *out*] (fn [] (binding [*out* saved-out] (foo)))) And use the created fn to start the other thread.

17:47 hiredman: it just makes instanciating a new fn complicated

17:47 spuz: bradford: Why didn't I think of checking clojure.contrib? :)

17:48 leafw: internal println was worse: String got printed as its contents, not as a double-quoted String. IS there any other preferable way of getting a {} into a file for later storage?

17:48 hiredman: leafw: don't use println

17:48 kotarak: leafw: prn

17:48 leafw: hiredman: ok

17:48 kotarak: ,(print "foo")

17:48 clojurebot: foo

17:48 kotarak: ,(pr "foo")

17:48 clojurebot: "foo"

17:48 hiredman: ,(doc pr)

17:48 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

17:49 bradford: when i load a new process now, i resolve by looking up symbols from namespace and fn string...like so

17:49 (defn retrieve-fn [namespace sym]

17:49 (let [ns-sym (symbol namespace)]

17:49 (apply use :reloadall [ns-sym])

17:49 ((ns-resolve ns-sym (symbol sym)))))

17:50 hiredman: bradford: why?

17:50 bradford: the issue now is that the client code (the code that is distributing functions onto remote processes) would like to extract the symbols for the ns and fn from teh fn instance itself.

17:50 kotarak: bradford: ??? doesn't namespace/sym suffice?

17:50 leafw: hiredman, kotarak : same error java.lang.ClassFormatError: Invalid this class index 3171 in constant pool in class file ini/trakem2/vector$eval__64 (SAT-lib-2.clj:1)

17:51 hiredman: hmmmm

17:51 well that is a different classfile

17:51 leafw: no, sorry, the ns was different

17:51 hiredman: are these aot compiled classes?

17:51 leafw: the file itself has just a map in it

17:51 a big, large map

17:52 bradford: so, given a fn instance, what is the simplest way to get its namespace and symbol?

17:52 hiredman: yeah, I mean the namespace calling load

17:52 kotarak: bradford: ah. You are talking about *processes* while I was thinking *threads*. Nevermind.

17:52 Chousuke: bradford: it may not have any

17:52 dakrone: I understand how to do something like (dotimes [d dice] (roll-dice sides)), but I don't understand how to collect & operate on the results of all the calls, can someone explain how to add all the results together to me?

17:52 bradford: right, im talking processes

17:52 kotarak: bradford: a fn instance doesn't have that.

17:53 bradford: so i can only get it from the var, right, i.e. ^#'foo

17:53 chouser: yes, named vars know their namespace and name

17:53 kotarak: dakrone: (take dice (repeatedly #(roll-dice sides)))

17:53 chouser: (not all vars are named)

17:53 hiredman: indeed

17:54 bradford: so can i look up a var from an instance that hte var is bound to?

17:54 dakrone: kotarak: awesome, very elegant, thank you much

17:54 hiredman: nope

17:54 leafw: ok, then time to report a bug in 1.1.0-alpha-snapshot

17:54 hiredman: a var is just a sort of pointer to some object

17:54 bradford: so none of this: (fn [x] (:ns (meta (find-var x))))


17:55 chouser: you could walk through ever var of every namespace looking for a value that matches

17:55 maybe you'd find one. maybe not.

17:55 bradford: i suppose i could just quote the function and lass the symbol around rather than the fn instance itself

17:56 rhickey: is the code on the remote site? if so why not just send the vars?

17:56 are you actually serializing fn bytecode?

17:56 hiredman: why not just send the whole .clj file

17:56 bradford: yes, the jar is on every machine with teh same code

17:56 leafw: rhickey: is there any know limitation in file size when load-file a very large .clj file?

17:57 hiredman: bradford: what!?

17:57 rhickey: then sending the var itself will unify with the var on the other side, since named vars are interned

17:57 bradford: hiredman: this is hadoop

17:57 rhickey: note, that is not the same thing as the symbol, the var itself

17:57 hiredman: bradford: so why bother?

17:58 I don't see why you need to do all this lookup stuff, if you have the samecode on every machine

17:58 chouser: presumably he wants to tell the other process which function to apply to a given task or data

17:58 rhickey: just send vars

17:59 that's what they are for, they do this already

17:59 bradford: right, i am just sening around ns/sym for function lookup

17:59 so i jsut send the var

17:59 rhickey: when read that var will be ready to call if it has the fn on the remote side, no lookup

18:00 bradford: as in... (eval-remote #'foo)

18:00 rhickey: simple reading #'rest will get you the var object

18:00 ,(read-string "#'rest")

18:00 clojurebot: (var rest)

18:01 rhickey: ,((read-string "#'rest") [1 2 3])

18:01 clojurebot: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn

18:02 hiredman: and clojurebot doesn't allow eval

18:02 rhickey: ack, yes, you will have to eval it

18:02 bradford: and this works because of the way var-lookup / interning works?

18:03 rhickey: but no lookup, since vars look themselves up when interning

18:03 right, every var with the same intern name is the same (identical) var

18:03 leafw: so, there are no known file-size limitations for load-file? How can a 6 Mb .clj file fail?

18:03 bradford: right, that's waht i mean, the interning process is built to do this lookup, so i shold be using it to do lookup rather than doing it myself

18:03 rhickey: i.e. (identical? (eval-remote #'foo) (eval-remote #'foo)) -> true

18:04 also identical to foo loaded remotely

18:04 in same ns

18:04 bradford: yes, let interning do it

18:05 bradford: great, this should simplfy some hadoop code we have.

18:05 rhickey: also note that the var is callable

18:05 chouser: could use 'resolve' instead of 'eval' -- would that be a poor choice?

18:05 rhickey: so vars are a good way to communicate about fn identity rather than value, presuming they are stored in fns

18:06 hiredman: rhickey: maybe you could weigh in on leafw's read problem?

18:07 rhickey: if it's a data file you'll hit the constant pool limit for class files, use read for data files, not load

18:08 leafw: ( hiredman: I can wait. The current conversation is instructive)

18:09 rhickey: chouser: resolve is about symbols, not vars, but could resolve a fully-qualified symbol to get var, yes

18:09 leafw: that's for you above ^^ use read, not load, for data files

18:09 hiredman: oh

18:10 oh!

18:10 I see read vs. load

18:10 leafw: rhickey, hiredman : thank you.

18:11 and you mean read and not load-reader?

18:15 hiredman: load-reader and load both go through the compiler

18:15 leafw: load-reader also fails. Ok.

18:15 (just tested)

18:19 yay read survived, with a PushbackReader that had 4096 size.

18:26 yuras: what is the opposite fun of (keyword x)?

18:27 somnium: yuras: you're probably looking for 'name

18:27 djork: hey are there better ways to configure jline?

18:27 I'm missing a good bit of the features I am used to

18:28 like Emacs-style editing (C-d delete, M-b or M-f jumping)

18:28 leafw: I am impressed by the way at how fast clojure can parse a 6 Mb map from a file. Its almost subsecond.

18:32 hiredman: Clojure: It's More Fn

18:32 StartsWithK: djork: you can configure jline if you write your own clojure launcher with jline api, there was/is a project that does that on google code, but i can't remeber the name of it or thoes is still exist

18:33 djork: Jline docs are nonexistent as far as I can tell

18:33 StartsWithK: does*

18:33 somnium: hiredman: will that be the T-shirt slogan for clojure-conf '10 ?

18:33 hiredman: chouser could put that on a shirt

18:34 djork: hah nice

18:34 hiredman: clojurebot: zazzle?

18:34 clojurebot: excusez-moi

18:34 hiredman: http://www.zazzle.com/clojure+tshirts

18:35 somnium: that logo would look good on coveralls

18:36 StartsWithK: djork: http://wrost.blogspot.com/2009/08/clojure-tab-completion-on-windows.html maybe this will help

18:36 leafw: continuing ... what is the best way to create a sorted map from an existing map? sorted-map requires elements unpacked from a list, so (sorted-map (interleave (keys m) (vals m))) cannot work. So how?

18:37 djork: that site is the only site on the entire internet that documents jline.words

18:37 leafw: (I am trying to avoid (TreeMap. m), which would work, but adds a java dependency)

18:37 rhickey: ,(into (sorted-map) {:c 1 :b 2 :a 3})

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

18:37 leafw: into. The magic word of the day. Thanks.

18:38 yuras: into made my day today. very magical thing and yet works nicely

18:38 leafw: into seems to emulate the constructor that most java collections have, combined with the addAll

18:42 kotarak: btw: does anyone else have problems with the group? My posts take sometimes over six hours to show up. :(

18:43 leafw: haven't noticed anything like that kotarak, but I have not checked properly.

18:44 rhickey: kotarak: I moderate several times a day, and I think chouser does as well

18:44 kotarak: It started sometime ago, when I was suddenly banned. :(( chouser fixed that. But since then I have trouble with terrible delays.

18:44 leafw: another quirk: clojure.set/intersection can't work with a key set obtained from a map: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentSet

18:44 StartsWithK: i am using clojure 1.0.0, to do unit test i have to load 16 test namespaces and there dependencies, it takes 4 seconds to load them? is this normal? (there is no aot)

18:44 rhickey: we've had a problem with spammers spoofing legit members. I had to moderate myself!

18:44 kotarak: o.O

18:44 hiredman: StartsWithK: 4 seconds from a cold jvm?

18:45 StartsWithK: hiredman: no, only to (require) test namespaces

18:45 hiredman: hmmm

18:46 well, you have to go to disk to load each file, and each file has to be read and compiled

18:46 StartsWithK: i know, but still, 4 sec to load something like 32 files

18:47 hiredman: clojurebot has the largest set of namespaces of any of my projects, and it takes a few beats to load, but I've never checked to see where that time is spent, could just be waiting to make the irc connection

18:47 leafw: and a pseudo-quirk: I would expect the collection returned by vals on a sorted map to implement List interface, since it's ordered. But java.util.TreeMap doesn't either.

18:49 same for the sorted keys.

18:50 and I am wrong: it does!

18:50 ,(ancestors (class (vals (into (sorted-map) {:a 1 :b 2}))))

18:50 clojurebot: #{java.lang.Object clojure.lang.Seqable clojure.lang.IPersistentCollection java.util.Collection clojure.lang.ASeq clojure.lang.IMeta clojure.lang.Streamable clojure.lang.Sequential java.lang.Iterable clojure.lang.IObj :clojure.contrib.generic/any clojure.lang.Obj java.util.List clojure.lang.ISeq}

18:51 StartsWithK: there is total of 34 namespaces and 16 namespaces with tests, non compiled

18:51 jhawk28: another favorable article from Tim Bray: http://www.tbray.org/ongoing/When/200x/2009/10/27/Recur

18:53 StartsWithK: funny thing is, i (read) every file of my project, at least until i hit first ns declaration in it, and it takes 1ms to do that for all the files

18:53 so i think its a compiler

18:57 djork: "But it seems obvious to me that recur is better than tail-call-optimized recursion." true dat

18:58 * djork is the guy who just grokked tail calls today

18:58 djork: so don't take his word for it

18:58 hiredman: I need to finish messing around with my reader so I can start messing around with the compiler

19:00 StartsWithK: a new reader? in clojure or java?

19:00 hiredman: clojure

19:01 * StartsWithK thinks of style preserving source code transformations..

19:01 hiredman: yeah

19:01 StartsWithK: that would be nice, clj->html, lint, formating..

19:01 hiredman: just rewriting LispReader.java into clojure/reader.clj

19:02 spuz: I have a question about code style. In java I often declare local variables even if they are only referenced once so that I can break up the code and also make it more self documenting. In clojure which of the following styles is preferred?

19:02 lisppaste8: spuz pasted "Local variables in clojure" at http://paste.lisp.org/display/89396

19:02 hiredman: http://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj a few missing pieces and needs to be cleaned up and better build integration

19:04 do you really want to self-document google's auth api?

19:04 spuz: hiredman: ?

19:05 hiredman: you are basically documenting google's auth-token api

19:05 from the client side

19:06 which, I mean, who cares? if you have some hairy function it's nice to break it up into chunks, but if it is just hitting some other standard api, *shrug*

19:07 spuz: I wouldn't say it's a standard API, it's not as if you can hover over it and see what it expects as arguments...

19:07 hiredman: spuz: I can just google it

19:07 spuz: heh

19:07 hiredman: I would document what is userdetails is supposed to be

19:08 spuz: it's not just the auth api, it's all of the parameters which have to be pieced together into the request string

19:08 hiredman: which is just a detail of the api

19:08 spuz: yep ok

19:08 jhawk28: hiredman: line 189 - misspelling ;)

19:09 hiredman: jhawk28: huh?

19:09 in eval-reader?

19:09 jhawk28: allowed instead of allow

19:09 hiredman: ah

19:09 *shrug*

19:09 jhawk28: hehe

19:09 hiredman: I guess that is important

19:10 StartsWithK: hiredman: will the final reader also be regex based?

19:10 hiredman: eh?

19:11 I'd hardly call it regex based

19:11 spuz: hiredman: so would you say it's fair to say that in clojure or any lisp, the way to document your code is to break it up into smaller functions, rather than into local variables?

19:11 hiredman: it uses 4 regexs in 4 or 5 functions

19:12 StartsWithK: hiredman: yes, your right, i just looke at the top of the file

19:12 hiredman: spuz: no

19:12 jhawk28: any idea when a function will allow more than 20 parameters?

19:13 hiredman: I would just say who cares about the details of google auth? if you are doing something interesting or tricky, break it up and document it by all means

19:13 spuz: hiredman: that sounds like a yes :p

19:16 StartsWithK: hiredman: this style you use with <string> sufix and such, is that something special in clojure 1.1 or new naming convention?

19:16 hiredman: if you are passing a map, I recommend map destructering

19:17 Chousuke: jhawk28: max parameter count will actually go *down*, not up :P

19:17 jhawk28: if you need more, use a rest parameter

19:18 hiredman: StartsWithK: nameing convention

19:18 LispReader has two static methods with the same name that vary on the type of the first param

19:19 StartsWithK: i have some macros that have more than one variant, so foo expands or to foo-1 or foo-2, is foo<1> prefered in general?

19:19 its hard to find any style guides on clojure code :)

19:20 hiredman: I dunno

19:20 <foo> might not technically be a valid symbol

19:20 Chousuke: it is.

19:21 StartsWithK: I'd find more descriptive names than -1 and -2 :P

19:21 hiredman: are you sure? clojure.org/reader says alphanumeric plus a handful of symbols

19:22 which don't include < or >

19:22 Chousuke: except < and > exist as functions :)

19:22 hiredman: so does /

19:22 Chousuke: yeah, but that receives special treatment anyway

19:23 hiredman: StartsWithK: aslong as you are consistent, I just like <1> visually

19:23 StartsWithK: Chousuke: its hard when they are only used to parse two different syntax variants of the same macro, so foo -> (or foo-1 foo-2) -> foo* is the best i can think of in such a case

19:24 hiredman: I'm not sure I even need those particular macros

19:24 but I am sticking with a direct translation of LispReader

19:24 StartsWithK: i don't think it gets more descriptive with that, i tried something like foo-with-only-properties-defined foo-with-properties-and-dependencies, but that is just too long

19:24 Chousuke: so wait, you're actually working on your reader now ?:P

19:25 hiredman: yeah

19:25 I stopped working on my old gen-class reader

19:25 Chousuke: I still have to find that bug with my reader :P

19:25 StartsWithK: how will clojure use reader in clojure?

19:25 hiredman: I've been grinding on thew new fractal letfn reader for the past week

19:26 somnium: you guys should agree on some tests and benchmarks so you can compete :P

19:26 Chousuke: StartsWithK: it's not easy but it's possible.

19:26 StartsWithK: old one will need to be there to bootstrap it?

19:26 Chousuke: only once )

19:26 StartsWithK: or will clojure keep its a jar of older version for that?

19:27 hiredman: I have ant compile java+clj, compile my reader, then delete compiled clojure (keep the compiled java), then recompile clojure using my compiled reader

19:28 my clojure prints "falling back to java reader" to System.err at startup if it can't load the cinc reader

19:28 Chousuke: I don't think I'll have time to work on mine for a while

19:29 hiredman: :(

19:29 Chousuke: and that bug I'm seeing... I have *no* clue.

19:29 hiredman: my syntax reader doesn't work either

19:29 Chousuke: the stacktrace mentions macroexpand and definline and whatnot but nothing there looks wrong.

19:30 so I bet its some error that just build up until it finally triggers there.

19:30 builds*

19:30 hiredman: yeah

19:30 Chousuke: I think it might be because I'm using a syntax-quote macro instead of just expanding it at read time.

19:31 but that would suck.

19:31 hiredman: it turns out I had a bunch of bugs, and because of my incremental fall back to LispReader they weren't exposed until I replaced read-delimited-list

19:31 Chousuke: ;(

19:31 hiredman: which exposed two or three bugs in other readers, which drove me crazy

19:31 Chousuke: :)

19:32 I think I might be encountering additional problems due to the pushbackreader (ew state :()

19:32 hiredman: because for a while I thought I was just missing something in read-delimited-list

19:32 Chousuke: I originally wrote the reader to work on a seq of characters

19:32 hiredman: hmmmm

19:32 Chousuke: then adapted it a bit to use a pushbackreader

19:32 hiredman: wouldn't it be easy to just turn a pbr into a seq of chars?

19:33 Chousuke: yeah, but turns out you need some "read-ahead"

19:33 at least one character

19:33 for example, if the input is "foo\n" then to read the symbol foo you need to consume the \n too

19:33 but that confuses the repl )

19:33 so you need to put the \n back

19:35 hiredman: you just cons the character back on :P

19:35 Chousuke: hiredman: except that won't work.

19:35 hiredman: as it's gone from the *stream*, which the repl uses

19:35 hiredman: :(

19:36 Chousuke: also for some reason attaching line metadata to objects causes the init method code to grow to ~90k which is over the 64k limit

19:36 hiredman: hmmm

19:37 Chousuke: if I change the metadata attaching function to identity, it works :P

19:37 but I get no line metadata.

19:38 but not having line metadata makes it so much harder to debug ;(

19:38 Raynes: I think I just found the thing that will make me stop using VimClojure. :\

19:39 The weirdness of namespaces.

19:40 StartsWithK: Raynes: what weirdness?

19:40 Raynes: You can't just open any file apparently, it tosses an error because of namespace crap. I have to open the file (it has to be on the servers classpath) and then \rf the file, and then close and then reopen the file. Apparently.

19:40 * Raynes notes his overuse of the word 'apparently'.

19:40 somnium: huh, just tried to build 1.0 branch of contrib with clojure 1.0 and it blew up

19:42 Raynes: At least, according to this: http://www.mail-archive.com/clojure@googlegroups.com/msg10657.html, it's the expected behavior. It's annoying behavior to me. :\

19:44 It's a bit of a dream killer.

19:45 technomancy: if you ever feel bummed out by the fact that clojure is a relatively new/immature language, I recommend http://planet.lisp.org to set you right again.

19:45 particularly things like http://trittweiler.blogspot.com/2009/10/0affff.html

19:46 Raynes: Are you talking to me? >_>

19:46 technomancy: sort of

19:48 Raynes: Nothing to do with Clojure. I have no earthly idea why VimClojure works like that. I was just trying it out anyways. I just doubt I'll continue using it if this is supposed to be a "feature".

19:52 tomoj: come to the dark side

19:59 Raynes: tomoj: If you were implying that I should use Emacs, I already do. I've just been playing with Vim for a few days to see what all the fuss was about. But after discovering this retarded little 'feature', I'm not sure what the fuss /is/ about.

20:00 tomoj: there's fuss about vimclojure?

20:01 somnium: I like vim, but I never managed to get vim clojure to work after two tries

20:01 is the clojure-1.0 jar on google code broken?

20:01 leafw: somnium: it's no big deal really.

20:01 tmountain: anybody know if there's a library floating around to do https requests?

20:03 StartsWithK: tmountain: apache commons httpclient can

20:03 tomoj: I imagine java can help cook one up pretty easily

20:03 ah, :)

20:05 jhawk28: tmountain: the Jetty client can too, but it doesnt support https through a proxy

20:06 tmountain: I'm trying with technomancy's client now, and pointing it at https://www.google.com/ gives me a 302 moved response

20:06 I wonder if that's verification that it works...

20:07 technomancy: word of warning: that is not a particularly well-tested library.

20:07 I'm only now starting to use it in real code as of like a week ago.

20:07 tmountain: no worries, I'm using it for a pet project

20:07 trying to hack together a google wave bot in clojure

20:07 technomancy: perfect; that's exactly what it was designed for

20:08 (pet project, not wave)

20:08 tmountain: yeah, it seems to work fine at the level I'm using it, so I don't forsee any problems

20:09 rewriting old Java code in Clojure really makes you realize how much unnecessary ceremony Java has

20:10 like... I can just rip out these 15 lines and replace them with this one-liner

20:10 it's crazy

20:11 technomancy: if that's surprising you either haven't been doing java very long or you've been doing it waaaaay too long. =)

20:13 somnium: tmountain: I just had the opposite experience, I needed to write a little java proxy class and was amazed at how excruciatingly painful it was after getting used to clojure

20:17 jhawk28: tmountain: you probably need to import the cert into the store

20:20 tmountain: I think you guys misunderstood me

20:20 I'm saying Java code is too freakin' long

20:20 heh

20:21 funkenblatt: misunderstanding implies that they actually read what you wrote

20:21 yuras: :)

20:21 funkenblatt: which i think may be assuming too much

20:21 yuras: i found even python code too long after clojure idioms

20:22 tmountain: agreed

20:22 * Raynes looks for Meikel Brandmeyers email address.

20:29 yuras: can somebody help me to make this func more clojurish http://gist.github.com/220108 ? or is it already okay?

20:39 somnium: yuras: you could use reduce instead of loop

21:42 bmidgley2: are there any working applet demos out there?

21:43 chouser: yeah, there was a thread on the group recently

21:46 bmidgley2: chouser: the google group? I couldn't find it

21:47 chouser: ok, I'll look.

21:49 http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Creating_an_Applet

21:52 tomoj: comes up for me when googling "clojure applet"..

21:52 maybe my google knows I want to see that

21:53 one might wrap some reads in a dosync to ensure a consistent snapshot, even though there's no writes, right?

21:56 rlb: Is there already something that lets you get a sub-command's stdout as a java stream? i.e. (line-seq (:stdout (sub-process ["find" "-type" "f" ...])))

21:57 chouser: tomoj: yes

21:58 tomoj: there's the thing in java

21:58 bmidgley2: ok, I guess I need a newer java6... none of the examples I found would run

21:58 tomoj: if it's wrapped in clojure I haven't seen it

21:58 chouser: rlb: I don't think so. there's shell-out in contrib, but it reads the whole output before returning to help uncomplicate resource management

21:59 rlb: right -- I need a stream

22:00 perhaps I'll look in to it...

22:00 chouser: you can consult the source there to see how to go about it

22:01 I've considered tweaking it to allow for an api like (with-process-stream [] ...)

22:01 bmidgley2: hmm... http://www.xenoage.com/extern/zongblog/eartraining/ gives me "Loading Java Applet Failed..."

22:01 in firefox on osx 10.5.8

22:01 chouser: rlb: that would close and clean up when you leave that dynamic scope. Would that fit your use case

22:01 bmidgley2: java 1.6.0_15

22:02 chouser: bmidgley2: yeah, macs give clojure applets trouble.

22:02 bmidgley2: too bad

22:02 chouser: bmidgley2: there's some discussion here: http://tinyurl.com/yfbbfjs

22:02 bmidgley2: our usergroup is in a clojure discussion now

22:03 rlb: chouser: might.

22:03 tomoj: ,(line-seq (java.io.BufferedReader. (java.io.InputStreamReader. (.getInputStream (.exec (Runtime/getRuntime) "echo hello")))))

22:03 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute)

22:03 tomoj: darn

22:03 chouser: tomoj: but note that leaves the streams open and the process running or in a zombie state

22:04 rlb: chouser: though perhaps I'll handle this particular problem differently -- might skip the sub-process and have clojure handle everything. Though I think I'll still want a way to get a lazy sub-process stream eventually.

22:04 tomoj: chouser: noted

22:04 hmm

22:04 I don't see any "echo" is ps -A

22:05 rlb: (Someone will need to wait() on the sub-process unless that's handled elsewhere.)

22:06 chouser: hm

22:06 that was my understanding as well, but the process does seem to be gone

22:07 rlb: Perhaps java handles that indirectly.

22:11 bmidgley2: aha!

22:11 I have 1.6.x at the command line but only 1.5.x in the browser

22:13 slashus2: bmidgley2: Look at your java preferences in your utility folder.

22:15 bmidgley2: it has a 64-bit java se6 first in the list for the applet plugin

22:15 does the browser choke on 64 bit plugins

22:16 slashus2: try the 32 bit java 6

22:17 bmidgley2: I don't have that in my list

22:17 downloading the latest java for osx... we'll see

22:21 chouser: I think I may have been misreading the java docs

22:22 I think the Process instance may wait for the process and handle the clean up for you.

22:24 If that's the case, then the streams are as safe to use as any other stream and shell-out could be a lot less picky.

22:28 tomoj: so is my line above bad or not?

22:30 chouser: it's bad.

22:30 wooby: has anyone investigated using simple build tool to compile/package clj stuff?

22:32 somnium: wooby: ant works for me

22:32 * Raynes- uses ant

22:32 somnium: wooby: and netbeans will generate a build.xml for you if you create a clojure project, though I haven't done it more than twice

22:33 hiredman: ant has some annoying issues

22:33 I really wish ant would not rebuild a dependency unless something was changed

22:34 wooby: yeah i'm not so much into ant

22:34 i really got used to sbt, and the dep handling especially

22:34 the transparent ivy goings-on

22:34 hiredman: <3 make

22:34 wooby: make pretty much rules

22:35 chouser: tomoj: this is apparently good enough though: (with-open [s (java.io.BufferedReader. (java.io.InputStreamReader. (.getInputStream (.exec (Runtime/getRuntime) "echo foo"))))] (vec (line-seq s)))

22:35 hiredman: I see a lot of work going into maven+clojure

22:35 but I haven't tried that out

22:35 somnium: I wonder how jruby-rake would do

22:38 tomoj: chouser: I see, thanks

22:40 hiredman: xml xml xml everywhere

22:40 ~xml

22:40 clojurebot: XmL is case-sensitive

22:41 hiredman: ~xml

22:41 clojurebot: xml is like violence; if it's not working, you're not using enough of it.

22:41 wavis_: zomg hiredman, that made my evening

22:42 rlb: Does clojure specify anything about the evaluation order of args?

22:42 chouser: yep, they go in order

22:42 rlb: i.e. do you need a let when order is important?

22:42 hiredman: l-to-r

22:43 rlb: hiredman: guaranteed?

22:43 arohner: rlb: yes

22:43 hiredman: really? I know that is how it works, but is that specified somewhere?

22:43 arohner: all lisps I know of do left-to-right

22:43 scheme specifies it

22:44 hiredman: *snort*

22:44 arohner: CL probably does too

22:44 rlb: arohner: I don't think it does.

22:44 chouser: yeah, I'm pretty sure it's guaranteed. eval order of literal maps is not guaranteed

22:44 rlb: From r5rs: "The operator and operand expressions are evaluated (in an unspecified order)"

22:45 hiredman: I know I read somewhere that some lisp goes the opposite order, but that was some old paper

22:45 rlb: In the case I care about, it's critical i.e. (vector (read-from-stream) (read-from-stream) (read-from-stream)), etc.

22:45 hiredman: there have doubtedly been lazy evaluation lisps

22:46 rlb: Perhaps I'll just use a let for now and worry about that later...

22:46 hiredman: rlb: I tihnk it would be clearer to put it in a let regardless

22:47 arohner: http://www.lispworks.com/documentation/HyperSpec/Issues/iss279_w.htm

22:47 tomoj: "The subforms in the cdr of the original form are evaluated in left-to-right order in the current lexical and dynamic environments."

22:47 CL

22:49 hiredman: clojurebot: what does the hyperspec say about evaluation order?

22:49 clojurebot: what is wrong with you

22:49 hiredman: ~botsnack

22:49 clojurebot: thanks; that was delicious. (nom nom nom)

22:50 arohner: http://lib.store.yahoo.net/lib/paulgraham/acl2.txt

22:50 hiredman: clojurebot: hyperspec?

22:50 clojurebot: hyperspec is not applicable

23:05 rlb: Is it possible to do a precise read from java - the equivalent of read(fd, buffer, 32)?

23:05 tomoj: has anyone seen NullPointerExceptions on trying to print something?

23:06 rlb: This has to be binary, and a single read, not a sequence of character reads.

23:06 (I'm trying to read data from a device on /dev/input/event*.)

23:06 tomoj: I mean like this: (class foo) => c.l.PersistentStructMap, (str foo) => NullPointerException

23:06 rlb: It's trivial in C, but I'm not sure how to get clojure to do it.

23:08 tomoj: oh it's because one of the values in the map is a lazy seq

23:08 the backtrace is unfortunately not at all helpful

23:36 rlb: Nevermind -- got it, (.read stream byte-array-size-n) seems to work.

23:46 Licenser: somnium: aloa

23:49 wwmorgan: how can I test whether an object I have is an array?

23:53 scottj: wwmorgan: there are vector? and type

23:53 wwmorgan: and seq?

23:55 wwmorgan: type is what I'm looking for. Thanks

23:58 hiredman: ok

Logging service provided by n01se.net