#clojure log - Nov 30 2009

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

0:01 _ato: ,(re-pattern (str "hello" "world"))

0:01 clojurebot: #"helloworld"

0:01 _ato: :-P

0:01 _mst: even better :)

0:02 qed: ah so I should just (let [regex-pattern (re-pattern s)])

0:02 thanks

0:04 if i have some list of strings

0:05 how can i search that list of strings for a regex

0:05 (filter #"text" coll)?

0:07 _ato: ,(filter #(re-matches #"a.*") ["apple" "cat" "dog"])

0:07 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--7967$fn

0:07 _ato: ,(filter #(re-matches #"a.*" %) ["apple" "cat" "dog"])

0:07 clojurebot: ("apple")

0:07 _ato: ,(filter #(re-find #"a.*" %) ["apple" "cat" "dog"])

0:07 clojurebot: ("apple" "cat")

0:07 _ato: depending on what kind of matching you need

0:09 qed: thanks _ato :)

0:11 _ato: nullpointer exception

0:11 anyway to avoid that?

0:14 http://gist.github.com/245271

0:14 what am i doin wrong there?

0:16 _ato: what line are you getting the NPE on?

0:16 qed: (i should add (search-text "test" (tweet-text 100)))

0:16 _ato: (if SLIME is giving you some no-source file rubbish, use C-c C-k to compile)

0:16 qed: when i run (search-text "test" (twett-text 100))

0:17 i get an NPE

0:17 _ato: right, but in the stack trace, where's the NPE

0:17 or you mean it's on that line?

0:17 qed: im in a repl

0:17 not sure how to find the line

0:18 _ato: it should say in the stack trace

0:18 it should at least tell you what function it's in

0:18 even if it doesn't have the line

0:18 qed: 17: user$eval__2442.invoke(NO_SOURCE_FILE)

0:18 that line i hilighted

0:18 _ato: huh... that doesn't sound right :/

0:18 qed: 0: clojure.lang.LazySeq.sval(LazySeq.java:47)

0:19 _ato: can you pastebin the whole stack trace?

0:19 qed: sure

0:20 http://gist.github.com/245274

0:20 _ato: ah

0:20 press "1"

0:21 konr: Is there any recipe to turn [1 10 100 1000] into [9 90 900]?

0:21 _ato: debugging Clojure 101: keep pressing "1" until pressing "1" is not an option. ;-)

0:21 then you'll get a more useful stack trace

0:22 1: [CAUSE] Throw cause of this exception

0:22 ^ I mean until that line isn't there anymore

0:23 qed: 0: java.util.regex.Matcher.getTextLength(Matcher.java:1140)

0:23 _ato: right

0:23 so it sounds like you're trying to run the regex on a null string

0:23 _mst: ,(map #(apply - (reverse %)) (partition 2 1 [1 10 100 1000]))

0:23 clojurebot: (9 90 900)

0:24 rzezeski: ,(into [] (take 3 (map #(* 9 %) [1 10 100 1000])))

0:24 clojurebot: [9 90 900]

0:24 _ato: qed: I'd guess (tweet-text) is not always returning a string

0:24 _mst: *laughs*

0:24 qed: _ato: yeah that's true

0:24 _mst: we may need more information :)

0:24 qed: is there anyway to get rid of nils before i run it

0:25 _ato: (filter #(re-find regex-pattern %) (remove nil? coll))

0:25 qed: nice

0:25 thanks _ato

0:26 _ato: ,(next (map #(* 9/10 %) [1 10 100 1000]))

0:26 clojurebot: (9 90 900)

0:27 _mst: ,(list 9 90 900)

0:27 clojurebot: (9 90 900)

0:27 _mst: maybe the input was just a decoy :)

0:27 konr: oops, I forgot to say what it was supposed to mean. I want [n1 n2 n3 n4] turned into [(- n2 -n1) (- n3 n2)] etc

0:28 _mst: this is good news for my first attempt :)

0:28 konr: ah-ha, I think _mst's answer is right

0:28 qed: ah yes, searching 10,000 tweets for "fuck"

0:28 konr: thanks!

0:28 qed: so classy

0:29 thank god we have computers to let us search for curse words

0:32 now i need to do something more interesting

0:35 wow. people who use "fuck" in their tweets are generally trashy

0:35 either trashy or emo

0:41 anyone know where i can find r. hickey's jvm language summit video in full?

0:44 _ato: qed: it's on infoq.com

0:44 http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

0:44 or do you mean there's something missing from that?

0:45 qed: found it

0:45 thanks

0:45 _ato: do you teach IRL?

0:46 _ato: if you dont you should consider it, you are one of the most supremely patient people ive met in any community

0:46 you seem passionate when it comes to showing others how things work

0:47 _ato: thanks. :-)

0:48 and no I don't teach IRL, in fact I haven't finished undergrad yet (I'm thinking of switching to a shorter degree and just graduating though, I'm getting sick of uni, so not always so patient :-P)

0:48 qed: i keep failing out

0:49 i take a course and it gets me interested in some dark corner where i work and learn, not getting credit for it

0:49 oh well

0:49 the things i have learned which i have received no formal credit for

0:49 are the most important things ive learned to-date

0:52 _ato: Yeah, I have that problem as well. Purely theoretical stuff (like proofs of correctness and such) just bore me. That's part of the reason I'm considering changing degrees, I don't think I'm really suited to academic-style research, I like research by tinkering not research by formalism. ;-)

0:54 I definitely think the CS degree was worthwhile starting with though, it meant I could skip all the zaney software engineering courses and did teach me a lot of useful stuff I wouldn't have otherwise encountered (compiler theory, automata/turing machines, lambda calculus etc)

0:56 rzezeski: can anyone point me to a function that acts like partition but doesn't truncate the remaining items?

0:57 _ato: rzezeski: sure, it's called 'partition' ;-)

0:57 ,(doc partition)

0:57 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

0:58 _ato: give it an empty "pad" argument

0:58 rzezeski: I guess that's not in 1.0.0?

0:58 technomancy: rzezeski: maybe partition-all from seq-utils in contrib

1:00 _ato: ,(partition 3 3 [] [1 2 3 4 5])

1:00 clojurebot: ((1 2 3) (4 5))

1:00 _ato: ,(partition-all 3 [1 2 3 4 5])

1:00 clojurebot: ((1 2 3) (4 5))

1:01 _ato: looks like that does the trick for 1.0

1:03 cgordon: I'm trying to use Leiningen, so I downloaded the latest "lein" script and ran "lein self-install". That put a jar file in ~/.m2/..., but when I run "lein new some-name", I get: Exception in thread "main" java.io.FileNotFoundException: Could not locate leiningen/new__init.class or leiningen/new.clj on classpath

1:04 If I do a "jar tvf ..." on the lein jar file, there is no leiningen/new.clj

1:05 _ato: cgordon: lein new doesn't exist in 0.5.0 (the latest stable release)

1:05 cgordon: _ato: ah, that would explain it :)

1:05 are there instructions somewhere for using lein with swank/slime from Emacs?

1:06 rzezeski: that'll do it, thx guys

1:07 _ato: cgordon: you don't need to do anything special with slime. Create a file project.clj with your dependencies (there's an example in the lein README). Create a directory "src" for your code. Run "lein deps" to grab dependencies and chuck them into "lib". Fire up emacs and hit M-x swank-clojure-project and give your project's directory path

1:08 cgordon: I don't seem to have a swank-clojure-project command in emacs, is that bundled with a new version of swank-clojure, or is that part of lein?

1:08 _ato: it's in a new swank-clojure

1:08 cgordon: also, where is lein getting dependencies from? Clojars? What about regular Java jar dependencies?

1:09 _ato: it checks maven central, clojars and build.clojure.org/snapshots

1:09 cgordon: _ato: thanks!

1:09 _ato: you can search maven central here: http://www.jarvana.com/

1:31 G0SUB: I am trying to design a very simple object store using a vector where objects expire after a while and the store is replenished with new objects.

1:31 any idea how to manage the expiration of objects?

1:41 Is clojure.org down?

1:46 tomoj: doesn't seem to be

2:00 G0SUB: tomoj: hmm, it's up now.

2:29 tomoj: is there a way to get the arity of a fn?

2:30 c.c.repl-utils/show suggests not

2:33 _ato: ,^#'inc

2:33 clojurebot: {:ns #<Namespace clojure.core>, :name inc, :file "clojure/core.clj", :line 618, :arglists ([x]), :inline #<core$fn__4729 clojure.core$fn__4729@1b0b0c1>, :doc "Returns a number one greater than num."}

2:33 _ato: hmm

2:34 tomoj: seems defn gives you :arglists

2:34 but not on anonymous fns of course

2:34 anyway I think I've realized I don't actually need to this anyway :)

2:35 _ato: ~count arities

2:35 clojurebot: count arities is http://groups.google.com/group/clojure/msg/fb9930ba2a25d2dd

2:36 tomoj: cool

4:36 angerman: I have a seq of line-no of a file. I want to extract. how would I do that in a memory friendly way?

4:49 AWizzArd: angerman: are you lazily reading the lines from your file? For example using duck-streams read-lines?

4:49 angerman: AWizzArd: that's what I'm trying

4:51 konr: It's my first GUI application, how can I make it not look like crap? Take a look: http://scorciapino.com/pub/fotos/peso.jpg

4:54 AWizzArd: angerman: well, then it sounds that you are already on the right path. You can use (I think from Contribs seq-utils) the function indexed and then run filter over it. This would give you all those lines you want

4:55 hiredman: http://java.sun.com/j2se/1.5.0/docs/api/java/io/RandomAccessFile.html

4:57 AWizzArd: Or maybe this is also ok for you: (filter (fn [[i line]] (when (your-set-of-lines-you-want i) line)) (read-lines "some-file"))

4:58 uhm, (indexed (read-lines ...))

4:58 _ato: angerman: if your list of line numbers is also too big to fit into memory and is sorted, you could do something like this: http://gist.github.com/245377

5:02 noidi: konr, you could use qt4 :)

5:02 hoeck: konr: maybe use another gui toolkit, for example http://incubator.apache.org/pivot/ :)

5:03 noidi: http://qt.nokia.com/doc/qtjambi-4.4/html/com/trolltech/qt/qtjambi-index.html

5:03 konr: interesting, guys...

5:04 haha

5:04 http://qt.nokia.com/doc/qtjambi-4.4/html/com/trolltech/qt/qtjambi-pathstroke.html <- This certainly looks better

5:05 _ato: there's also alternative widget sets for swing: http://code.google.com/p/macwidgets/

5:10 konr: Does QT work flawlessly in Windows XP/Vista/7?

5:13 _ato: also try: (javax.swing.UIManager/setLookAndFeel (javax.swing.UIManager/getSystemLookAndFeelClassName))

5:19 Chousuke: konr: well, nothing ever works flawlessly, but... with the disclaimer, yes.

5:20 I guess there always are gotchas when writing crossplatform UIs but Qt is pretty good.

5:27 noidi: konr, one caveat regarding qt jambi: http://qt.nokia.com/about/news/preview-of-final-qt-jambi-release-available

5:28 it is no longer developed by qt software, and they will end support for it next year

5:29 I haven't followed the project so I don't know whether an open source community has taken over the maintenance or not

5:32 apparently there is already a port of Jambi for the next QT release http://qt.gitorious.org/qt-jambi/community-port-to-4_6

6:23 AWizzArd: Chousuke: funny, what you said is impossible I think. I mean your rule/law "nothing ever works flawlessly". If this rule were true then the nothing also points to itself. So the truth of your statement leads to its untruth :)

6:34 ,java.io.File/separator

6:34 clojurebot: "/"

6:35 AWizzArd: is there something like this for determine line endings on the given system, such as "\n" for Unix and Gnu, "\r\n" for Windows and "\r" for OSX?

6:37 ,(System/getProperty "line.separator")

6:37 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission line.separator read)

7:55 AWizzArd: rhickey: Is this a new exception? java.lang.VerifyError: (class: my/namespace/program$my_fun__2984, method: invoke signature: (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;) Expecting to find integer on stack

7:56 rhickey_: AWizzArd: verify errors are my bad - what's the code/Clojure version?

7:56 AWizzArd: I get this in a loop where I have (loop [n (foo xyz)] ...) and where foo is (defn #^int foo [x] ...)

7:56 When I remove the #^int return value type hint this error goes away.

7:57 It is {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}, from the New branch from Thursday (Nov. 26)

7:58 rhickey_: AWizzArd: no Clojure fn can return an int primitive

7:58 your type hint is a lie

7:59 AWizzArd: ah okay, I und

8:01 chouser: rhickey_: it would be pretty easy (and apparently desirable to dysinger and other maven consumers) to use the :qualifier for the branch name.

8:03 rhickey_: just a one-line patch to each branch that seems worth naming (I was thinking master and new)

8:03 rhickey_: chouser: fine by me

8:06 chouser: ok, thanks. I'll coordinate with dysinger

8:36 AWizzArd: Is it already possible to type hint deftypes?

8:36 (deftype person [a b c]) (defn #^person foo [] ...)

8:38 chouser: AWizzArd: shouldn't be necessary

8:39 (:a (foo)) should give you field-access speed without type hints.

8:40 AWizzArd: How would it be known at compile time that foo returns a person?

8:42 rhickey: AWizzArd: what code need to know that or could leverage it? Also, person is not a class

8:42 at least not yet :)

8:43 * rhickey added lateral class resolution to DynamicClassLoader this morning, grand plans ahead

8:51 cemerick: rhickey: does that mean finding classes loaded in sibling classloaders? (surely not?)

8:51 rhickey: yup

8:51 just the dynamic ones

8:52 cemerick: oh, this is only intra-clojure

8:52 rhickey: also, no-op reload of identical class, load new version of class with same name

8:52 cemerick: yes, just for Clojure stuff

8:52 cemerick: rhickey: OK, right. Thought you were really changing the rules on us somehow. :-)

8:53 rhickey: cemerick: well, it should enable new features

8:54 right now I'm focusing on the underpinnings of protocols/defclass, but this could e.g. support dynamic definterface

8:55 er, deftype

8:55 not defclass

8:56 AWizzArd: I just liked the idea to document my code with type hints.

8:56 cemerick: defclass is gone for good, right?

8:56 AWizzArd: instead (defn foo [string] ...) I prefer (defn foo [#^String s] ...)

8:57 rhickey: cemerick: it's a naming thing, certainly there's no reason for 2, deftype covers both use cases. But it looks like deftype might be able to generate what feels like a named class even in the dynamic case, including across redefs

8:57 AWizzArd: Without type hints lispers sometimes are tempted to name a var after its type.

8:58 chouser: AWizzArd: I see that in fully statically-typed code too

8:58 cemerick: rhickey: That's good, if only so that some of that naming real estate is available for people building object systems.

8:58 rhickey: AWizzArd: using type hints that way is a bad idea

8:58 chouser: AWizzArd: either with hungarian or something less formal

8:59 rhickey: cemerick: the only question would be which to choose - if types no longer need the IDynamicType stucc, i.e. are classes, is defclass the better name?

9:00 AWizzArd: becasue type hints mean something, they are not just comments

9:00 AWizzArd: Yes, and I would only pass in the right types.

9:00 cemerick: rhickey: the weaker the construct's support for all of the trappings of jvm/clr classes, the more I'd lean towards deftype

9:00 ...regardless of the underlying impl, I mean.

9:00 rhickey: cemerick: that's my inclination as well

9:01 AWizzArd: rhickey: what is the lateral class resolution to DynamicClassLoader good for? I mean, what are your grand plans? :)

9:01 rhickey: anyway, seems like a clear path now to protocols/deftype/reify with no reference even to interfaces, reify of protocols

9:01 reify of interfaces and deftype implementing interfaces just about interop

9:04 AWizzArd: lateral class resolution means I can dynamically generate named classes, and find them in other dynamic classloaders, without trying to insert them in some shared root in the hierarchy (an impossible task given modular classloaders, context classloaders etc)

9:04 chouser: how do the lateral class loaders find each other?

9:04 rhickey: lifts a prior restriction on named things being static only

9:05 chouser: they don't see each other, but see the dynamic classes of all, in a shared cache

9:05 now named things need be static only for other static things

9:05 AWizzArd: And if you use a dynamic classloader, does this then mean you can gc those named classes?

9:05 rhickey: the cache holds the classes in weak refs

9:06 * chouser shudders

9:06 rhickey: but it also allows for no op redefs, caches the hash of the bytecode

9:06 if same, just returns existing class

9:07 so you could intermix definterface or deftypes in a file with code, reload won't invalidate unchanged classes

9:08 this also means that both deftype and reify can implement protocols based on interfaces always, not just when AOTed

9:08 chouser: this is what weak refs are for, canonic caches

9:10 the upside is huge

9:11 definterface (formerly gen-and-load-interface), no problem, including redefs

9:11 deftypes could gen named classes, with same name, all the time

9:11 protocols can always gen a corresponding interface, not just AOT

9:12 reify can easily implement protocols

9:12 chouser: yeah, that's a bit stunning

9:13 rhickey: the only hitch will be a true (altering) redef of a type will require a reload of client code to work with new instances, but no JVM restart ever

9:14 I basically decided following the tree design was simply too restrictive, was never intended to cover these cases, and hell, why should these modularity systems have all the fun - they do this kind of thing all the time

9:15 chouser: heh

9:15 rhickey: it's still early, but I'm quite hopeful

9:17 so, when protocols generate interfaces I want to cover 2 things:

9:17 first, there needs to be name munging, as the protocols fns will become interface methods

9:17 I can hide this munging so deftype and reify use the clojure names

9:18 the second thing I want to do is allow for multiple protocols to have the same named functions, without merging or clashes

9:18 this will require that the method names in the interface have something about the protocol as a prefix or suffix

9:19 again, as with munging, deftype and reify will hide this

9:19 but, should you want to extend the protocol from JAva, you will see these names

9:20 chouser: these would be multiple protocols each in their own namespace with the same unqualified method names?

9:20 rhickey: yes

9:20 right now that is a weakness of interfaces - the names merge

9:20 and can conflict if, say, only return types differ

9:21 never mind any semantic conflicts

9:22 so, if protocols Bar and Baz both define foo, would become methods: Bar__foo(), Baz__foo(), or foo__Bar(), foo__Baz()

9:22 chouser: semantic conflicts that could actually cause an extend to want different functionality for two methods with the same name (and args and even return type) from different protocols

9:23 rhickey: yes, definitely, the functions in separate namespaces mean different things

9:24 CLR doesn't do merging anyway, it is a broken part of Java

9:24 also a broken part of most open-class OO systems

9:24 classes make lousy namespaces

9:24 chouser: CLR languages provide extra syntax to disambiguate on method calls?

9:25 rhickey: so, the question is, would those pre/suffixes be bad

9:25 chouser: yes, both on calls and definitions, you can define overrides for Bar::foo and Baz::foo in the same class

9:25 cemerick: rhickey: pretty cringe-inducing *shrug*

9:26 rhickey: which makes sense, because when calling you will be using the Bar or Baz interfaces

9:26 cemerick: not sure what a good alternative would be

9:26 rhickey: just like in Clojure you will be using the Bar or Baz namespaces

9:26 cemerick: right, alternatives welcome

9:27 cemerick: rhickey: how about defining inner interfaces?

9:27 chouser: any chance of also generating prefix-less methods that just call the real one?

9:27 * cemerick might be missing the point

9:27 rhickey: chouser: when there is only one?

9:28 cemerick: the problem is the method name, not the class structure

9:28 chouser: rhickey: right, for the probably common case of there being only one. Dunno if there's an appropriate moment to hook in order to leave it out on multiple.

9:28 rhickey: two interfaces both have a foo method, with different semantics, and you want to implement both

9:29 chouser: the problem there is that, should you in the future implement another interface with an overlap, that redirector will disappear

9:29 breaking clients

9:29 chouser: yeah, I guess my idea won't work, since both would produce the prefix-less methods, and would just have a conflict the moment some Java code tried to implement both.

9:30 yeah, that too. :-(

9:30 rhickey: also, the clients will be using the interfaces, not the concrete class

9:30 chouser: ah, right -- no redirect code allowed in interfaces.

9:30 broken on so many levels! oh well.

9:30 rhickey: so, protocol Baz looking for foo will be looking for foo_Baz

9:31 this aspect of JAva is broken, and I'd prefer not to have protocols be broken too. Right now the story is, same function name in different namespaces ok

9:32 and use of interfaces for speed under protocols is an implementation detail

9:32 chouser: always using a prefix/suffix would dissallow the kind of "transparent" client use by Java code I'm using right now.

9:34 rhickey: chouser: there are slightly different requirements at play here. There, the Java interface is driving, it won't be the primary interface to the protocol

9:34 I'm thinking about designs where some substantial facility has been built in clojure on protocols, how to write new Java to work with it

9:35 chouser: I have Java clients doing things like RPC.newChannel("target").send(myMessage), where RPC is gen-class with static methods, and the Channel interface is from gen-interface. 'send' is implemented via proxy

9:35 rhickey: JAva code can't presume all implementors of protocol implement some interface - that will never be true, since extends lets protocols reach classes with no derivation requirement

9:36 chouser: so for that you might still want definterface + deftype/reify

9:36 cemerick: rhickey: FWIW, in that use case, I'd say that a Java-friendly API should be written using genclass or a regular interface + deftype/reify.

9:36 heh

9:37 chouser: right. I'm fine with Java code that's aware of Clojure having to stretch a bit (munging in prefixes or whatever) to get at things that weren't intentionally made Java-friendly.

9:37 rhickey: if protocols are to be clojure-like, they will have name munging too

9:37 octe: i was thinking about creating a http loadtest program, as an exercise... make x requests using y concurrent clients

9:37 would it be a good idea to use agents for that?

9:37 rhickey: but, it could be possible, if you used compatible names and didn't get a prefix, to get a nice-looking interface from defprotocol...

9:37 chouser: ...as long as I can still do what I'm doing as well.

9:38 cemerick: my point being, I think any general solution to making clojure callable from Java will be less than what a real user would want.

9:38 chouser: octe: yep, probably.

9:38 octe: i was thinking you could create Y agents with a request-coutner as a value and keep sending of request requests to them until their total count reaches X

9:38 rhickey: cemerick: by regular interface above do you mean JAva-defined?

9:39 cemerick: rhickey: yes. If you're writing Java code anyway, and you want to call some clojure lib, I think it's totally reasonable to say that the work and shape of that integration falls on the integrator, not the language.

9:40 rhickey: the biggest problem of declaring 'no prefix' at the protocol side is that the clashes occur in client code doing ad-hoc extension

9:40 cemerick: someone in that position will likely be doing something you're not going to anticipate anyway, so punting to interface+reify/genclass will be the rule more than the exception, I'd wager.

9:40 rhickey: You can't be both a j.u.Map and a j.u.Collection, for example, due to this problem

9:41 one thing that is key is that if you have a protocol-driven design, and want to make it reach another, more Java friendly interface, you always can

9:42 but the protocol-specific interface gets a perf benefit that can't be gotten otherwise

9:44 I guess if I leave in :on, you could make protocols where a definterface drives that, but :on is really ugly, puts a discussion of interfaces up front, has name-mapping and other required knobs...

9:45 but it is a key question - are there many cases where a pre-existing interface should be the basis for a protocol?

9:46 chouser: my code is already partitioned into core functions vs. clojure api (which includes macros) vs. java api (public interfaces, static factory methods, etc.) ...so I have no problem with internal clojure stuff that might look "ugly" to Java, as long as I can still wrap it up in stuff that looks pretty in Java without actually writing any Java. :-)

9:47 rhickey: (definterface Pretty ...) (extend Pretty MyProtocol ...)

9:47 chouser: rhickey: do clojure's java.util-extending classes not fit that description?

9:49 rhickey: chouser: no, the primary consumption on the Clojure side is via Clojure's interfaces, which will become protocols. deftypes will implement the j.util stuff so they can be passed across

9:49 usually protocolizing a java interface won't help JAva, since you can;t make a Java String a Java Collection

9:50 protocols break free from the derivation requirement

9:51 Chousuke: rhickey: you haven't added a seq1 function (for "unchunking" a seq) yet, have you? I suppose it would be good to have in 1.1 if people need it :/

9:52 rhickey: the other route is to do name-munging only, people can easily avoid munging by using compatible names. You would be precluded from implementing protocols with overlapping functions in the same deftype, but could still reach the other protocol with an extend-type

9:53 Chousuke: that's definitely something we need to look at pre 1.1, yes

9:54 so, no merging

9:54 but no prefixes

9:54 never stuck due to extend-type

9:54 have to pick which protocol you want 'fast'

9:55 that's not so bad

9:56 if protocol is my.ns/Protocol, interface is my.ns.Protocol?

9:56 I'm trying to avoid knobs

9:57 doublindirection: hello #clojure

10:06 cemerick: rhickey: sounds like a perfectly reasonable approach that (most importantly, IMO) doesn't try to be a general solution.

10:21 konr: (-> f .getName .toLowerCase (.endsWith ".jpg"))

10:21 -> is so awesome.

10:22 angerman: is there a math (arrays) lib from clojure?

10:29 looks like the incater matrix is pretty ncie

10:39 cemerick: Looks like I need to rebind a multimethod with one that temporarily contains an additional set of methods. Is there a better way to do this, short of using defmethod before (binding...) and remove-method in a finally? (Thankfully, I'm not worried about race conditions in this case.)

10:41 patrkris: Is there a video available of the Clojure Experience talk (http://tinyurl.com/ygb5t8m)?

10:41 Couldn't seem to find one

10:42 chouser: cemerick: the same defmultis, but for additional types?

10:42 cemerick: chouser: right

10:42 chouser: weird. and it's no good to just leave them in place all the time?

10:44 cemerick: there's an outside chance that leaving them in place all the time will cause strange bleed-through of behaviour from one lib to another, depending on load order

10:44 rhickey: patrkris: not as far as I know. It was a talk I gave recently at MIT CSAIL, and it was videotaped

10:44 patrkris: rhickey: ok, would love to watch it

10:45 chouser: it looks like the standard clojure intro, but updated post JVM lang summit.

10:45 cemerick: actually, any naming collision of the keywords used as args to the multimethod will cause problems, so I definitely wouldn't want to leave in method impls

10:46 rhickey: the intro stuff went by quickly. many in the audience had seen both my Boston talk (3 hrs) and ILC tutorial (5 hrs)

10:46 cemerick: (this calls for a persistent MultiFn impl :-P)

10:49 octe: hmm, probably somethings stupid but.. http://paste.lisp.org/display/91271 <- why does this code end up making 25 requests?

10:50 chouser: cemerick: add/remove is the only way I can think of, but I suppose I can imagine each methodtable living in, say, an atom in a var so that the var could get thread-local bindings.

10:50 cemerick: still seems pretty weird to me. :-P

10:51 would mess with the caching

10:54 cemerick: eh, dispatch table caching is not a cost relative to the rest of the app

10:54 chouser: the specific situation is an indexing system where documents are {:name "val" :name2 "val"}, and different callers need to have control over how the values are indexed (tokenized or not and how, stored or not, etc). If document type A has a field :foo that should be tokenized, and document type B has a field :foo that shouldn't be tokenized, this has to be controlled in a context-sensitive way.

10:55 I guess I could use a two-stage approach.

10:55 chouser: and multimethods have been a good fit up to this point?

10:55 cemerick: no, this is a new addition -- so far, indexing params have been hardcoded based on the type of the value

10:56 chouser: rhickey: I think at least 3 books on the way: one from APress, two from Manning

10:56 rhickey: should be interesting to see how they differ

10:56 chouser: indeed

10:58 my vague understanding is that the prag, apress, and "in action" from manning are essentially meant to be head-to-head competition, while we're making ours try to come at things from a slightly different angle.

10:59 rhickey: chouser: lucky you!

10:59 chouser: heh

10:59 we'll see. :-)

10:59 cemerick: chouser: yeah, a 2-stage approach is better in general -- multimethod dispatching on document type returning a fn (or var that can be rebound as desired) that provides the actual configuration

11:00 although the method-table-in-an-atom idea is a good thought :-)

11:02 G0SUB: what is a nice way to emulate expiration of data after some time?

11:03 I have some access tokens which expire after 1 hour and need to be renewed.

11:03 a thread monitoring the tokens periodically is one way.

11:04 chouser: G0SUB: you want renewal triggered by time, or by attempted usage after a time limit?

11:04 G0SUB: chouser: the latter is OK with me.

11:05 I am fine with both, actually.

11:05 chouser: for the latter, you can just timestamp the object. Maybe in metadata, depending on other usage.

11:05 G0SUB: I get the tokens from an external system, and I have 3 api calls to create, destroy and validate the tokens

11:06 hmm

11:17 AlexStoddard: I have large data where I expect different instances to share a lot of structure (genetic variation in humans - representable as a vector or sequence). Clojure's structural sharing is mostly explained in terms of changes over time not changes between individuals. Any suggestions on how I might leverage structural sharing in Clojure to efficiently represent the data?

11:22 Chousuke: AlexStoddard: can't you just model your data as a progression of individuals instead of as progression of time? :/

11:23 AlexStoddard: if you make a "modification" to a vector, it would represent a new individual, but the structure would be shared with the parent individual.

11:26 AlexStoddard: Chousuke: That is what I am thinking, the abstraction makes sense. What I am unsure about is how to "attach" an individual to each given state of the vector.

11:27 Chousuke: Each state *is* an individual. but you could have a ref to point to one of the individuals (changing over time) and call it pinnacle-of-evolution or something. Or you could have sets containing these individuals, or whatever

11:28 chouser: AlexStoddard: the structural sharing is pretty invisible. Just hang onto one version of a thing, do some 'assoc', 'dissoc', etc. to get to your next object, then hang onto that as well.

11:30 Chousuke: if genetic change can happen within one individual then you need to model them as time-dependent. eg. you need a ref to give an identity to the individual, or if that's too granular, a whole population (which "progresses" synchronously)

11:34 AlexStoddard: chouser: So it would be as simple as (def ind1 (load-genetic-vector)) (def ind2 (mutate ind1)) and ind1 and ind2 share structure?

11:36 liebke: AlexStoddard: yes, ind1 and ind2 will share structure

11:36 mattrepl: chouser: how should one choose bugs in assembla to work on? it's not clear what fields like "approved" mean. I'd like to help out, but not sure what's higher priority

11:37 chouser: mattrepl: yeah, it's a bit confusing. I started on a flow chart once... ...

11:37 mattrepl: it's generally pretty flat. "approved" is only when there's a patch attached that rhickey has examined and agrees is ready to be committed.

11:38 "test" means someone has submitted a patch but rhickey hasn't approved it yet.

11:39 rhickey: mattrepl: something useful right now would be to go through the existing tickets and set any missing Types

11:39 bug vs enhancement

11:40 mattrepl: chouser: thanks, that makes sense

11:40 rhickey: http://twitter.com/neal4d/status/6189294802

11:40 mattrepl: rhickey: sure thing

11:41 chouser: everything else is fair game for writing patches -- I guess "milestone" gives a sense of priority

11:41 mattrepl: are tickets in the backlog ok to work on or do they need to be reviewed for relevancy?

11:41 AlexStoddard: liebke et al: Thanks, persistent vectors for genetics, here I come...

11:42 rhickey: yes, there were a whole bunch of things slated for next release that got ignored, while others from backlog got worked on, so didn't seem to make much sense to me to keep trying to do that, but the approved backlog are things I think are more important

11:42 chouser: mattrepl: if they exist at all it's ok to work on them, though they might need more design discussion or might not make it in anytime soon.

11:43 mattrepl: ok, thanks

11:45 rhickey: wow, this instant interface thing will be game changing:

11:45 (defprotocol P (foo [x]) (bar ([x] [x y])))

11:45 (defn baz [x] (bar x))

11:45 (baz (reify [user.P] (.bar [] 42)))

11:45 ;will become (baz (reify [P (bar [] 42)]))?

11:46 does beg the implicit this question again...

11:47 cemerick: rhickey: one thing stuck out for me in those slides that are making the rounds this morning: "composability of independent decisions e.g. thread pool sizing". That's developing into a big issue for our UIs -- e.g. running a pmap in a UI app simply kills the entire system. Definitely good utilization, but being able to say "this pmap/send/future/etc should go into this low-priority/N-thread/etc threadpool/executor" woul

11:47 incredibly useful.

11:47 rhickey: I hate to see all those unused thises

11:47 Chousuke: rhickey: I'm fine with either choice as long as its applied consistently :)

11:48 proxy already has implicit this so that's one argument for it, I suppose.

11:48 rhickey: Chousuke: what's consistent though? - interface sigs are declared without this, protocol fns have an arg for it, and both may appear together in a single deftype

11:49 you are bound to have one mismatch

11:49 Chousuke: hmm, right. Java complicating things again :P

11:50 rhickey: cemerick: definitely want to have more pool options, but still leaves basic questions unanswered - how do independent decisions interact>

11:50 there is implicit scope already in play in deftype - unqualified access to fields

11:57 notallama: cemerick: i wrote a different version of future the other day that uses a daemon thread pool (http://paste.lisp.org/display/91277). that's something you can hack together yourself, if you want. for send, i think you have to change Agent.java (i didn't see another way to do it)

11:57 cemerick: rhickey: absolutely. The brute-force approach leads to insanity. Further, I presume that the way j.u.concurrent does things is not suitable for .NET or cocoa or js or..., so I suppose clojure needs a higher-level set of levers than all of the fiddly bits that j.u.c provides.

11:58 rhickey: cemerick: I think you miss my point - I consider this an unsolved problem

11:58 i.e. for which I don't yet have an answer

12:03 cemerick: Well, I'd think a first step of having bindable vars for the executors in Agent (as notallama's impl points towards) would be a good 80% solution.

12:03 Certainly leads to proliferation with various libs potentially keeping their own pools around, but that's what thread schedulers are for.

12:04 rhickey: cemerick: meh, I think at least moving towards ForkJoin work-stealing.

12:05 cemerick: rhickey: well, that's JDK7 only, no?

12:05 rhickey: works with JDK 6

12:05 but not 5 :(

12:05 cemerick: oh, that's interesting. Isn't there a native component, though?

12:05 rhickey: no, just JSR166y.jar

12:06 see par branch

12:06 works today on 6

12:06 cemerick: huh, I never looked at that at all because I had it in my head that it was JDK 7-only

12:06 rhickey: has a fjtask, like future, but joins any enclosing fjtask

12:38 arohner: is there a way to introspect a deftype to get the number and order of the args in the constructor?

12:38 I'd like to pass a map literal to make a deftype instance. if I could introspect, I could write the fn to do it

12:39 djork: hmm, every time I try this failing 'use' expression in my repl, it increments the line number associated with the error

12:39 is that a bug?

12:40 like, it starts at line 1, then just goes up by one each time

12:40 chouser: arohner: you can use the arglists of the factory fn pretty safely I think.

12:41 arohner: chouser: aha, thanks

13:03 rhickey: hmm, clojure.contrib.pprint.PrettyWriter has an illegal method name: col-write

13:06 qed: heh that was fun, i ran a search for 250,000 incoming tweets for clojure

13:06 w/ clojure of course

13:07 i wonder how many tweets there are in a day

13:12 look like ~25 million per day

13:12 tmountain: qed: according to this guy's blog, 27.3 million - http://www.briansolis.com/2009/11/guess-how-many-tweets-fly-across-twitter-each-day/

13:12 qed: http://popacular.com/gigatweet/

13:13 tmountain: too bad they use scala :-p

13:13 qed: hehe

13:13 im gonna grab a day of tweets and see what I can do with it

13:20 rhickey: so I'm left with the conflict between the name of a protocol and its implicit interface - user/P and user.P

13:23 Chousuke: rhickey: would it be too ugly to just prefix the interface name with P or something?

13:23 rhickey: Chousuke: yes

13:41 ok, protocols gen interfaces is up!

13:42 noidi: how can I drop every second item from a seq?

13:43 Chousuke: ,(let [x (atom false)] (filter #(swap! x not) [1 2 3 4 5 6]))

13:43 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--8041$fn

13:43 Chousuke: hmm

13:43 oops

13:44 ,(let [x (atom false)] (filter (fn [_] (swap! x not)) [1 2 3 4 5 6]))

13:44 clojurebot: (1 3 5)

13:44 noidi: thanks

13:44 Chousuke: there's probably a better way, but...

13:44 noidi: that works but the atom is not too pretty

13:45 the-kenny: Chousuke: That was my first idea too.. But I'm sure there is a better way

13:45 maybe seq-utils/indexed + for or something

13:45 noidi: ah, indexed

13:45 that was the thing I was looking for, but I couldn't remember the name

13:46 the-kenny: noidi: It's in clojure.contrib.seq-utils.

13:46 noidi: thanks

13:46 that + filter odd? should probably do the trick

13:46 Chousuke: indexes :(

13:47 esj: or (map first (partition 1 2 '(1 2 3 4 5 6))) ?

13:48 noidi: esj, of course! brilliant! :)

13:48 thanks

13:49 esj: noidi: don't take my word for it, i'm habitually wrong.

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

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

13:51 noidi: ,(map second (partition 2 (range 10)))

13:51 clojurebot: (1 3 5 7 9)

13:51 noidi: nice and simple :)

13:54 esj: cool.

13:55 noidi: weird, I can load the triangles of a 3D mesh from a COLLADA file in 13 lines of clojure

13:56 coming from an imperative/OO programming, functional code feels amazingly dense

13:56 the-kenny: noidi: That's true

13:56 noidi: dense as in little fluff, not dense as in difficult to read

13:57 polypus: niodi, yeah i'm rewriting a genetic programming project from ruby and it is an order of magnitude smaller

13:57 noidi*

13:58 hey do you guys know if there is any audio/video available anywhere of rhickey's semantic web talks?

13:59 technomancy: I wish I understood more than 20% of this, but it's a good read nonetheless: http://blogs.sun.com/jrose/entry/tailcalls_meet_invokedynamic

14:03 esj: anybody knows if json.write has gone away ?

14:03 (use 'clojure.contrib.json.write) doesn't seem to work

14:03 ?

14:07 rhickey: noidi: (take-nth 2 (range 10))

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

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

14:07 esj: rhickey: nice.

14:07 rhickey: Chousuke: shame on you for that atom stuff!

14:08 noidi: rhickey, you win :)

14:09 esj: he has an unfair advantage... and not just that he's super clever :)

14:11 cemerick: are tail-calls really on the table for JDK 7 now?

14:11 rhickey: cemerick: not as far as I know

14:12 technomancy: cemerick: according to John Rose it's a matter of manpower

14:12 cemerick: that's what I thought, though I see the post that technomancy just linked to, and there was a java.net post about first-class continuations in JDK 7 over the weekend, so I thought maybe something was afoot

14:13 technomancy: IMO: http://twitter.com/cemerick/status/5868285825

14:13 rhickey: If all this stuff is going to be in JDK7, then JDK7 is a long way away

14:13 cemerick: from a selfish user standpoint, of course ;-)

14:17 shr3kst3r: change java 7 to java dnf

14:52 technomancy: cemerick: I guess the guy working with Rose on that was doing it for his Ph.D thesis, but then he graduated. =(

14:53 cemerick: bah

14:53 and there's a small squad of folks puttering away building the javafx stack. Awesome.

14:54 * cemerick is glad he could get his Sun angst in for the day

14:57 djork: does anybody else worry about the future of Sun's JDK?

14:57 like, that they will be around at all?

14:57 are they financially sound at all?

14:57 rsynnott: couldn't people just use the open-source version?

14:57 djork: well, Oracle is supposedly buying them

14:57 djork: oh great

14:57 rsynnott: (assuming that the EC can be satisfied)

14:58 djork: I wonder how Oracle will treat the JDK

14:58 err, JVM

14:58 will they further its development or hinder it

14:59 rsynnott: probably won't hinder it

14:59 they're pretty java-dependent

14:59 djork: yeah, I suppose so

14:59 rsynnott: of course, they may not be allowed to buy sun

14:59 djork: right

15:00 rsynnott: they will, of course, put it on a website of remarkable awfulness and make it harder to install

15:00 (that's pretty much Oracle's job)

15:00 djork: yeah I can't wait for Oracle Java 9-16R Enterprise Edition

15:01 lisppaste8: rhickey pasted "protocols gen interfaces" at http://paste.lisp.org/display/91296

15:04 chouser: bar-me takes either 1 or 2 args?

15:04 rhickey: right

15:04 chouser: I was sure for several moments that it was taking 1 arg and returning a vector length 2, and was trying to figure out where y was coming from.

15:06 rhickey: so you can implement protocols in deftype, and reify protocols

15:06 all of this is dynamic

15:07 chouser: that's really seamless

15:07 rhickey: munging occurs on the names in deftype and reify

15:08 still not sure about (.foo [] ...) vs (foo [this] ...)

15:08 I know the crowd here wanted explicit this

15:09 Chousuke: the argument lists in deftype managed to throw me off somewhat already.

15:10 rhickey: right now deftype and reify don't know or care that P is a protocol

15:11 whatever happens should be the same for interfaces and protocols (really, there are only interfaces in deftype and reify)

15:11 explicit this would align better with protocols, and less well with interfaces coming from JAva

15:12 the leading dot also seems weird if you are working only with protocols and deftype

15:15 lisppaste8: rhickey annotated #91296 "w/explicit this" at http://paste.lisp.org/display/91296#1

15:16 rhickey: explicit this, no dots

15:16 seems a better match for protocols

15:16 LauJensen: rhickey, so both explicit and mandatory for each method?

15:17 rhickey: LauJensen: whatever it is would be the same story for all methods, from interfaces and protocols

15:17 Chousuke: yeah, I like that better. it's more functional in style anyway

15:17 rhickey: you don't have to call it this, you could do [_] when you don't use it

15:17 or call it me or self or whatever

15:18 Chousuke: or it could be "handler" or whatever the object actually represents :P

15:18 LauJensen: rhickey, I think implicit this would be much more elegantly and feel quite natural in the jvm

15:18 Chousuke: LauJensen: looking at the previous example, I have to disagree with that :/

15:19 LauJensen: oh ok, np. good to have more views :)

15:19 Chousuke: it fits the java way where you have objects and "this" anyway, but it looks like magic in Clojure core. :P

15:19 code'

15:19 arbscht: I look forward to using clojure outside of the jvm. explicit would be nice ;)

15:19 rhickey: basic interface use of reify would be: (reify [ActionListener] (actionPerformed [this evt] ...))

15:20 LauJensen: Chousuke, I think ritually repeated the first argument which is a fixed ref to fixed is just ceremony in some regard

15:20 Chousuke: LauJensen: you don't have to always call it this.

15:20 LauJensen: I know

15:21 Chousuke: But especially off-putting is the mismatch between defprotocol definitions and deftype definitions in the implicit this example :/

15:21 I'd rather have some ceremony than that.

15:21 rhickey: I was very much in favor of implicit this when it was just about interfaces, now with protocols, alignment with protocols is primary concern

15:22 people can use protocols, reify and deftype and never know about interfaces

15:22 LauJensen: Sure, I didn't consider that. Consistency is supremely important

15:22 Which reminds me, doesn't it seem odd that nth doesn't take the idx as its first arg? Or is that just a gut feeling?

15:24 dnolen: rhickey: interesting so do the latest changes allow you to create Java interfaces on the fly?

15:25 rhickey: dnolen: right now, only with defprotocol, still thinking about what definterface should look like

15:25 but the machinery is in place

15:26 dnolen: rhickey: crazee cool :D

15:28 rhickey: what about the parens-mean-calls folks? the leading dot seemed to ease that somewhat, without it do reify and deftype get hard to parse?

15:29 LauJensen: rhickey, not sure Im following, parens-mean-calls?

15:29 chouser: reify no worse than proxy. defprotocol and deftype somewhat better because of being rooted at the top level.

15:30 rhickey: chouser: I presume you like the explicit this?

15:30 chouser: I think 'case' is my new favorite punching bag on that front.

15:30 rhickey: the dots really bother me when implementing protocols

15:31 chouser: yeah, I won't disagree with you there. I liked it when the only way you would call it was also with a dot, but defining with a dot and calling without just makes no sense.

15:31 for explicit this, I was going to check the logs to make sure I didn't disagree with myself...

15:32 rhickey: two other niggles are - in defprotocol, multiple arity goes in same form, in reify/deftype, multiple forms

15:32 notallama: with explicit this, you could destructure it, yes?

15:32 chouser: notallama: nice!!

15:33 rhickey: and, my.ns/Protocol (the protocol itself) my.ns.Protocol (the interface we don't want to talk about but need to name in reify/deftype)

15:34 notallama: not right now, no

15:34 chouser: I guess you'd only be destructuring fields that you already have direct access to, right?

15:34 or ... wait, I'm confused. do we have direct access in all contexts?

15:34 rhickey: chouser: yes

15:35 but bigger issue is these methods are not fns, don't have any destructuring of any args yet

15:37 chouser: I'm just not keeping up.

15:37 but that's ok. It's not as if me keeping up helps anyone. :-)

15:38 rhickey: chouser: not true!

15:38 what's unclear?

15:38 chouser: I'll catch up eventually.

15:39 my mental construct is a fragile collection of various versions of various of these pieces. stop thinking about it for a holiday weekend and I've got hardly anything left.

15:39 rhickey: :)

15:40 well, if I can iron out these few details I'll finish up and modify the docs to align

15:40 seems like few people would want the dot given protocols

15:40 andfew would want implicit this either

15:41 I guess people will have to use it a bit to see if my.ns/Protocol (the protocol itself) vs my.ns.Protocol (the interface) poses a problem

15:42 destructuring support would be nice, would need to make reify a macro

15:44 chouser: extend still takes maps of real fns, right? so destructuring and closures are there.

15:45 rhickey: chouser: yes, all that is the same

15:45 chouser: reify now works on protocols because each protocol has a matching interface.

15:45 rhickey: new today is defprotocol gens interface, opening up existing interface impl support in deftype and reify to protocols

15:46 chouser: I forget if reify does closures

15:46 rhickey: reify is a closure essentially

15:46 notallama: man. this was already my favourite type system about a week ago (when i tried new). and it keeps getting better

15:47 rhickey: see x in the paste

15:47 chouser: ok, right. the fields of the reify class are the closed-overs

15:47 rhickey: right

15:48 chouser: the methods of the reify class have direct access to its fields in the same way any closure does. But it also has methods as allowed by the interface as always but now also protocols.

15:49 deftype has been about interfaces, but now can do protocols as well. Does it just use the interface? Does that mean it's not splitting its body into deftype/extend?

15:49 rhickey: chouser: right, but the trick is to come up with the story from the other direction - imagine you don't know Java, and have been shown protocols and deftype. You can etend a type to a protocol externally or internally

15:50 solussd: could somebody explain the difference between send and send-off?

15:51 rhickey: externally with extend or extend-type, internally by putting ____ (called my.ns.Protocol) in square brackets and the definitions inline. The inline definitions have direct access to your fields, but are not closures over surrounding lexical scope (usually none)

15:51 additionally, you can do one-off implementations of a protocol with reify

15:51 notallama: solussd: send uses a fixed-size thread pool, send-off uses a variable-sized one. so, send can get clogged if you have slow/blocking functions, basically.

15:51 SergeyDidenko: Solussd, http://clojure.org/agents

15:52 rhickey: note the absence of 'interface' in the above description

15:52 perhaps interface must unavoidably go in ____ above

15:52 polypus: rhickey. was there any audio/video of your semantic talks ever released. google aint giving me anything. any plans for other talks on same subject?

15:53 solussd: thanks, http://clojure.org/agents doesn't explain the implementation difference, only usage scenarios.

15:53 rhickey: polypus: not as far as I know

15:53 chouser: not just "protocol name" for the ____?

15:53 polypus: rhickey: thx

15:54 rhickey: chouser: yeah, the trouble is my.ns/Protocol also names the protocol object

15:54 which is what you'll need for extend*

15:54 chouser: oh, I see.

15:54 SergeyDidenko: solussd, indeed. I thought I saw it there.

15:55 rhickey: chouser: that's one of the current niggles

15:56 SergeyDidenko: solussd, http://java.ociweb.com/mark/clojure/article.html#Concurrency see "Agents" section

15:56 chouser: surely anything that expects a protocol object my.ns/Protocol can figure out the interface name?

15:56 SergeyDidenko: solussd, it's a great artcile BTW

15:56 solussd: SergeyDidenko: excellent, thanks. I'll read it

15:57 rhickey: chouser: right now deftype and reify don't know about protocols

15:57 SergeyDidenko: Is the simplest way to translate '(n1 n2 n3 ...) into ((1 n1) (1 n2) (1 n3) ...) is to use "(partition 2 (interleave (repeat 1) '(n1 n2 n3 ...)))" ?

15:57 rhickey: but yes, given a protocol instance P the interface name is (:on P)

15:59 chouser: ,(map #(list 1 %) '(n1 n2 n3 ...))

15:59 clojurebot: ((1 n1) (1 n2) (1 n3) (1 ...))

15:59 rhickey: ,(map list (repeat 1) [2 3 4 5])

15:59 clojurebot: ((1 2) (1 3) (1 4) (1 5))

16:00 SergeyDidenko: Oh, I completely forgot about map :) Thank you

16:01 rhickey: we'd need to yank some innards from fn to enable destructuring in deftype and reify

16:01 chouser: rhickey: ok, I see. So either deftype and reify have to be taught (a little) about protocols, or users need to know about the two names for the protocol and when to use each.

16:07 alexyk: anybody here using clojure maven plugin?

16:07 konr: Is there a parser generator for clojure?

16:08 cark: konr : fnparse

16:09 hiredman: that is a parser, not a parser generator, innit?

16:10 cark: hum, at the end that's doing the same thing no ?

16:13 alexyk: any nice wrappers around joda time?

16:15 chouser: alexyk: I think the consensus has been it doesn't really need a wrapper.

16:16 alexyk: chouser: Scala adds things like < operator

16:16 can you redefine < for DateTime in clojure?

16:17 or, define

16:17 chouser: no

16:17 alexyk: hi mattrepl! I was just looking at your neo4j wrappers yesterday

16:17 chouser: makes it easier :)

16:18 cemerick: mmm, operator overloading.

16:18 chouser: alexyk: I can see that. I dunno if we'll get a protocol for < or not.

16:18 cemerick: 154227134 < some-date-obj, yay ;-P

16:18 mattrepl: hey alexyk, cool! they don't do much but hope they were useful

16:19 alexyk: mattrepl: I was just poking around... found several. Yours is just one file, right?

16:20 chouser: protocol is the OO parlance, right?

16:20 chouser: protocol is a Clojure feature in the "new" branch

16:20 But I guess I'm referring to a future beyond that: clojure-in-clojure

16:21 mattrepl: alexyk: yup

16:22 alexyk: how do I translate this Java into Clojure: DateTimeFormat.forPattern("<fmt>")?

16:22 chouser: alexyk: (DateTimeFormat/forPattern "<fmt>")

16:22 alexyk: that's the pattern for static method calls.

16:22 alexyk: ah right. I was trying (.forPattern DateTimeFormat.forPattern "...") and it was not finding it.

16:23 twbray: While you guys were Thanksgiving-ing, I was pounding away on Clojure with big data: http://www.tbray.org/ongoing/When/200x/2009/11/26/No-Free-Lunch

16:23 alexyk: I mean (.method Class "param")

16:24 twbray: nice! I was an eager collector of the Wide Finders scripts back in the day! Are you still running any?

16:24 chouser: alexyk: right, that would be treating DateTimeFormat like an instance of the Class class, looking for a method Class::forPattern or something.

16:25 bitbckt: "back in the day"... has it been that long, already?

16:25 twbray: alexyk: Yep, technology moves along.

16:25 alexyk: twbray: the Perl lead was mindboggling

16:26 twbray: we need a Scala/Clojure shootout with agents vs actors

16:26 rhickey: chouser: ok, that's better, so now after doing (defprotocol P ...) you can just do (deftype Foo [a b c] [P] ...)

16:27 alexyk: twbray: how about a JVM-only Wide Finder?

16:28 twbray: tweak your GC's, do whatever. Same Sun JDK; or may be OpenJDK and others, too.

16:28 twbray: alexyk: JVM is crippled on this problem compared to systems that don't have to turn texts into UTF-16 :(.

16:28 chouser: rhickey: deftype will take either an interface or a protocol object?

16:29 alexyk: twbray: then some other problem with juicy concurrency :)

16:29 hiredman: you just need a regex engine that takes bytes

16:29 alexyk: regex there was a weak link allowing a perl lead even

16:29 twbray: hiredman: Trying to make it *easy* for programmers. They just want to see strings.

16:30 chouser: hiredman: that's a good point. is there no string/regex lib for java that uses utf8 internally instead of 16?

16:31 alexyk: twbray: UTF-16 will work on Chinese web logs :)

16:31 twbray: chouser: There might be, but irrelevant. You wanna live in the java ecosystem, you got to live with Java strings :(

16:32 chouser: hmmm

16:32 twbray: Anyhow, not really relevant. The fact that Java burns CPU on this means that concurrency should be *more* valuable on a many-core system, deal the computing out.

16:35 cemerick: I'm a similar position as a few commenters on that post: does it matter at all, as long as wall-clock time is what it should be?

16:35 alexyk: Dmitriy talks of teams of 10 employers doing work in 1 day, very post-modern :)

16:35 cemerick: (outside of wattage burned, perhaps?)

16:37 twbray: cemeric: I'm not really sure whether or not the amount of CPU burned is significant. But it's still surprising. Anyhow, a speedup factor of four based on straightforward use of Clojure primitives without too much voodoo is obviously good.

16:38 cemerick: twbray: I guess my confusion is around what exactly a cpu cycle is, if not a corollary to a unit of time.

16:39 twbray: cemerick: In practical terms, what it means is, how many of the machines cores are in use & not available for other work.

16:39 On this computer, for every unit of time, there are 16 units of integer computing potentially available.

16:39 chouser: seems like it might matter a lot in a world of on-demand provisioned virtual machines billed by number of comuter-hours used.

16:39 alexyk: twbray: a bit offtopic, but perhaps you can shed the light. I got a box with 8 quad-core CPUs, but top never shows loads more than 800% CPU. In such setups, is it because 100% CPU is counted per each quad-core? It's a Barcelona Intel x86_64 each. Can such a system run 32 threads at once?

16:40 cemerick: chouser: thus my wattage remark. Thankfully a world I've no involvement in.

16:40 rhickey: chouser: yes, interface or protocol designators

16:40 twbray: alxyk: Don't know, depends on details of processor architecture & how it reports CPU time to the OS and how the OS reports to you.

16:46 tmountain: alxyk: make a shell script, and put one of these per line, per core - while [ 1 ]; do :; done &

16:47 alxyk: go into top after that, and you should easily be able to tell what your system reports when it's maxed out

16:50 the-kenny: I have a file with little-endian utf16-text. How can I read the file in clojure?

16:50 bitbckt: heh

16:50 SergeyDidenko: the-kenny, play with *default-encoding* ?

16:51 twbray: the-kenny: (def decoder java.nio.charset.Charset forName "UTF-8") newDecoder))

16:51 Oops, that UTF-8 should be UTF-16LE for you

16:51 the-kenny: Then you can call (. decoder decode) on a buffer

16:52 Chousuke: (.newDecoder (java.nio.charset.Charset/forName "UTF-16LE")) would be more idiomatic. :)

16:52 alexyk: is there any shorthand for the following two imports: (import [org.joda.time DateTime]) (import [org.joda.time.format DateTimeFormat]) -- or they have to stay separate?

16:53 the-kenny: twbray, Chousuke: Thanks, I'll try that :)

16:53 Chousuke: also (.decode decoder args) (assuming it's an instance method)

16:53 * Chousuke really doesn't like the . form much

16:53 * twbray agrees that Chousuke is perfectly entitled to his opinions as to what's idiomatic in the no-mans-land between Java & Lisp.

16:54 Chousuke: I will never stop trying to wean people away from using . directly. :)

16:56 It is, after all, in my best insterest to have people write code that I find readable :P

16:56 but I digress.

16:57 alexyk: Chousuke: is there any alternaive to, e.g.: (.parseDateTime dtFmt "2009-06-15 04:01:00") ; ?

16:57 Chousuke: that's the proper sugared form I think.

16:58 alexyk: Chousuke: ah, you mean (. <space> ...)

16:58 Chousuke: yeah.

16:58 also, I don't think there's any way to unify those import statements

16:59 though usually you'd have them in the ns declaration

16:59 eg. (ns (:import (org.joda.time.format DateTimeFormat) (org.joda.time DateTime)))

16:59 alexyk: Chousuke: I noticed that both Clojure and Scala abbreviate importing a list from the same package, but not across e.g. nested supbpackages. Is it based on JVM innards for import?

17:00 Chousuke: alexyk: subpackages and their parents are not actually related in any way, except by name.

17:01 it is possible to extend the ns macro to support (foo.bar subpackage.Class AnotherClass) but I don't know if that could create ambiguities.

17:02 alexyk: Chousuke: ah, I forgot it's a lisp and we got macros! would be cut to write a different ns and annoy people :)

17:02 Chousuke: heh.

17:03 (my-ns foo.bar (import-my-stuff))

17:03 jasapp: is there a better way to do this?

17:03 Chousuke: yeah, you could do that but you shouldn't :P

17:03 jasapp: ,(apply hash-map (list 1 2 3 4))

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

17:04 Chousuke: ,(hash-map 1 2 3 4); like this?

17:04 clojurebot: {1 2, 3 4}

17:04 jasapp: well, if the argument has to be a list

17:04 Chousuke: ah, then no.

17:04 alexyk: ok, so I see two different ways to interop with Java here: (.parseDateTime dtFmt "2009-06-15 04:01:00") and (. dtFmt parseDateTime "2009-06-15 04:01:00"); but this doesn't work: (dtFmt. parseDateTime "2009-06-15 04:01:00")

17:04 when do you use the form (Class. method ...) ?

17:05 Chousuke: the Foo. form is short for new Foo

17:05 jasapp: thanks

17:05 alexyk: ok

17:05 Chousuke: About Foo. and new Foo I don't really care which one you use. at least new is an informative operator, unlike . :P

17:07 alexyk: yeah, Class. method is confusing

17:08 (new Foo) is clearer

17:10 Chousuke: The Foo. syntax is convenient when you need to wrap things though.

17:10 the-kenny: hm... looks like the text isn't utf-16.. stupid windows mobile

17:10 Chousuke: like (BufferedReader. (FileReader. ...))

17:11 alexyk: right

17:12 can it be done with .. though?

17:12 or not for nested new's?

17:12 Chousuke: no.

17:12 .. is for calling methods

17:12 though I prefer using -> with .methods :)

17:13 alexyk: Chousuke: how would that work in my parseDateTime example above

17:13 ?

17:14 Chousuke: well, it's not very useful in that case

17:14 but (-> dtFmt (.parseDateTime "2009-06-15 04:01:00"))

17:16 alexyk: hmm... slightly bigger than (. ...) :)

17:16 can see better :)

17:16 Chousuke: yeah, but the real use is when you have a pipeline of operations

17:17 ,(-> "foobar" (subs 2 4) .toUpperCase); especially if you need to mix clojure functions and java methods

17:17 clojurebot: "OB"

17:18 alexyk: nice

17:19 Chousuke: or if you need to look up something in a deep data structure

17:20 ,(-> {:foo {:bar {:a 3 :b 1}}} :foo :bar :b)

17:20 clojurebot: 1

17:20 alexyk: now that's useful even in clojure-only!

17:23 Chousuke: it's actually a macro

17:23 it just reorders the operators a bit

18:50 defn: hey all

18:54 I have this silly thing where I'm searching for tweets which contain #"regex" -- I'd like to create two instances of this search, 1000 tweets each, and then combine their state

18:54 this is something I'd use refs for, yes?

19:00 nvm

19:39 rhickey_: ok - latest deftype/reify implements all discussed - no dots, no implicit this, can use protocol directly in deftype/reify protocol/interface lists, updated docs

19:41 KirinDave: Is there a special "last result" variable for the clojure repl?

19:41 I heard there was one, but I honestly can't find it.

19:41 rhickey_: *1

19:41 *2 *3 too

19:41 KirinDave: Thanks.

19:41 defn: there's also one for errors

19:41 *e I believe

19:41 exceptions, rather

19:41 ,*e

19:41 clojurebot: java.lang.IllegalStateException: Var clojure.core/*e is unbound.

19:42 KirinDave: ,*1

19:42 clojurebot: java.lang.IllegalStateException: Var clojure.core/*1 is unbound.

19:42 defn: hehe, not here though :)

19:42 KirinDave: Heh

19:42 cemerick: heh, no more dots on method impls, eh?

19:45 rhickey_: cemerick: no, they don't match protocols well at all

19:45 cemerick: ah, consistency. Well, I really liked them while they lasted. :-)

19:45 rhickey_: I think they made sense without protocols, but I want protocols to be the primary story, since now it is so good

19:46 cemerick: yeah, no argument from me

19:47 KirinDave: Is there a new description for protocols

19:47 ?

19:47 Besides the old thread on the list?

19:48 rhickey_: KirinDave: I'm tweaking the wiki now, but the inline (doc ...) should all be correct, for reify, deftype, defprotocol etc

19:48 defn: Is there any ongoing effort to provide real-world examples for the api documentation?

19:49 KirinDave: rhickey_: I will start fanatically clicking the refresh button in anticipation. :)

19:50 I'm excited about things that make noun-y programming a bit easier.

19:51 rhickey_: KirinDave: I'm not sure this does that

19:52 defn: I'm interested in building an expanded documentation project that adds some real world examples to the api documentation.

19:52 (where appropriate)

19:52 For things like (ns) it could be nice to have somewhere to document that sort of thing

19:52 KirinDave: rhickey_: My use case is very banal. I've been bugging people here about a foosball scoring webapp.

19:53 rhickey_: And I find it kind of tedious to have to write things like make-player and make-team.

19:53 rhickey_: defn: there is this: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Cookbook

19:53 _mst: defn: how about http://en.wikibooks.org/wiki/Clojure_Programming?

19:55 defn: That's pretty nice, I guess I would like to see something like ruby-doc.org/core

19:55 rhickey_: defn: not trying to discourage you, contributions welcome

19:56 defn: rhickey_: would it make sense to start a new project, or to submit to you additions to the current api documentation?

19:56 rhickey_: defn: the api doc is reference-style and is likely to stay that way

19:57 * defn nods

19:58 KirinDave: is clojure.contrib.seq-utils open for suggestions?

19:59 Just via the normal github process maybe?

20:00 rhickey_: KirinDave: there is the ggroup and contrib assembla

20:17 https://www.assembla.com/wiki/show/clojure/Datatypes and https://www.assembla.com/wiki/show/clojure/Protocols updated, feedback welcome

20:18 this all feels good to me now, please try it out

20:23 bitbckt: I don't think I've seen this asked, but forgive me if it has been...

20:23 "resulting functions dispatch on the type of their first argument"... why only the first?

20:24 rhickey_: bitbckt: there are multimethods if you want to do other than that

20:24 protocols let you reach the highest level of polymorphism perf available on the platform

20:25 bitbckt: I see. Multimethods are still to be preferred for multiple dispatch, then.

20:25 rhickey_: bitbckt: no other choice for that

20:26 bitbckt: Okay. Thanks. :)

21:14 arohner: I have a protocol. I have a deftype that implements a method on the protocol's interface. In my deftype declaration, I'm getting clojure.lang.Var cannot be cast to java.lang.Class

21:14 lisppaste8: url?

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

21:15 chouser: rhickey_: what about allowing (defprotocol P (bar [x] [x y])) for multiple args, rather than (bar ([x] [x y])) ?

21:15 lisppaste8: arohner pasted "deftype" at http://paste.lisp.org/display/91318

21:15 rhickey_: chouser: maybe, where do docs go?

21:16 I agree the grouping is unintuitive

21:16 chouser: hm, at the end I guess, where they do now.

21:17 name, vectors, then a string.

21:18 lisppaste8: rhickey annotated #91318 "deftype for latest" at http://paste.lisp.org/display/91318#1

21:18 chouser: arohner: your deftype doesn't look quite right

21:18 rhickey_: see annotation ^

21:19 no dots anymore, no [] around methods

21:19 arohner: my checkout is probably a week old. I'll update.

21:21 rhickey_: arohner: yeah, the version you are using doesn't support protocols in deftype

21:21 arohner: ah! that would be a problem. thanks

21:22 chouser: heh. This error message seems like it ought to be informative enough.

21:22 No single method: foo of interface: user.Foo found for function: foo of protocol: Foo

21:23 hiredman: ouch

21:23 chouser: maybe if I used names better than "foo" it would help :-P

21:26 rhickey_: chouser: what were you doing?

21:27 chouser: ooh, I can use 'show' to see the protocol methods implemented directly by a deftype

21:27 rhickey_: just playing at the repl

21:27 ...and I see what I did wrong.

21:28 so methods defined inline in a deftype get real methods in the resulting class, right?

21:28 rhickey_: yes

21:28 chouser: but anything added via extend doesn't?

21:29 rhickey_: right, can't, class is baked

21:29 chouser: right, makes sense.

21:31 arohner: so where do methods added via extend go?

21:32 rhickey_: they are fns in maps

21:33 stored in protocol itself

21:34 chouser: so, faster than multimethods but not as fast as a case or direct method call?

21:35 rhickey_: as fast as call through var, given caching. Doesn't lookup every time

21:36 chouser: ok, nice.

21:36 dnolen: rhickey_: so I saw that you mean somewhere that the inclusion of deftype will remove the need for type metadata pattern? or am I dreaming that up andi it's still useful? :)

21:37 mean -> mention

21:37 chouser: (deftype Foo [a b c] [] (foo [this] <<here>>)) ; at <<here>>, 'a' is the same as '(:a this)'?

21:37 rhickey_: dnolen: well, protocols won't use type metadata, so I expect it to fall by the wayside

21:38 chouser: there a is the same as (.a this)

21:38 hiredman: chouser: did you see my fn minus

21:39 rhickey_: looks like external protocol defs are broken, aargh

21:39 chouser: hiredman: no I didn't.

21:40 dnolen: rhickey_: so you expect that people that really want to define a type, will just use deftype over map plus metadata?

21:40 rhickey_: dnolen: yes

21:41 hiredman: http://paste.lisp.org/display/91148#1 this was more or less sitting in my head when I woke up thanksgiving morning

21:41 dnolen: rhickey_: duh, I forgot that deftype creates a type tag for you. It's so magical! :)

21:44 chouser: hiredman: did you just toss together a little tree-walking macro!?

21:44 * chouser keeps reading

21:44 hiredman: oh, it just uses tree-seq

21:45 very simple, which is why I called it fn minus, I was just kind of tickled by how easy it just falls out

21:46 chouser: so that's an implementation of fn in terms of deftype.

21:46 ?

21:46 hiredman: well AFn needs to be a protocol

21:47 hmmm

21:47 efarrar: is there a mechanism to override/overload java methods from clojure? I'd sure love it if javax.swing.JContainer#setPreferredSize() took a height and a width, and not a java.awt.Dimension

21:47 hiredman: IFn would be the protocol and AFn would just be a map of functions you can mix in

21:48 JAS415: efarrar: proxy?

21:48 efarrar: i'll check it out

21:48 thanks

21:48 hiredman: chouser: so yes then

21:49 efarrar: i thought that was just for interfaces

21:49 hiredman: proxy doesn't let you create new methods

21:50 efarrar: just write a function

21:51 (defn set-prefered-size [jcontainer height width] (.setPreferedSize jcontainer (Dimension. width height)))

21:53 efarrar: fair enough

22:01 rhickey_: ok, all fixed, grab latest if playing with new branch

22:08 arohner: hrm, github is lying.

22:09 git pull says I'm up-to-date, but the commit id doesn't match the github UI

22:09 hiredman: have to wait for the latest commit to replicate out

22:10 arohner: this time it worked

22:13 Base: Hi

22:15 rhickey_: Hi

22:21 arohner: is there a way to specify a default method for a protocol?

22:22 for all types

22:22 rhickey_: extend to Object

22:22 hiredman: maybe extend the protocol on Object?

22:23 ahem

22:23 extend to

22:23 rhickey_: will cover everything except nil

22:23 you can also extend to nil

22:23 arohner: thanks

22:25 dnolen: rhickey: can extend be used to add metadata support to fns?

22:25 rhickey_: dnolen: no

22:36 dnolen: technomancy: do you have to run lein install in the lein-swank directory first?

23:10 JAS415: hmm

23:10 i'm having trouble with the pprint package

23:10 ,(clojure.contrib.pprint/cl-format nil "~s" 1)

23:11 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.pprint

23:11 alexyk: is there any BitSet wrapper in clojure, or just JDK BitSet?

23:13 The-Kennz: JAS415: have you clojure-contrib.jar in your classpath?

23:14 technomancy: dnolen-rec: I pushed out lein-swank under the leiningen group

23:14 dnolen: technomancy: just now?

23:14 JAS415: yup

23:14 been using all of the other contrib stuff

23:14 technomancy: dnolen: no, a few days ago

23:15 dnolen: technomancy: so here's the deal, lein swank only works for me from the lein-swank folder in the leiningen checkout directory

23:15 technomancy: i can't get it to work at all outside that directory.

23:16 technomancy: dnolen: have you declared it as a dev dependency of the project you want to use it on?

23:16 dnolen: technomancy: yup

23:16 technomancy: can you paste your project.clj?

23:16 dnolen: :dev-dependencies [[leiningen/lein-swank "1.0.0-SNAPSHOT"]]

23:16 https://gist.github.com/4cefd43eca404c351f22

23:17 I added the swank-clojure dependency as a debug shot in the dark, I don't think that's required

23:17 technomancy: no, it should get pulled in automatically

23:17 ah, did you run lein deps to pull in all the dependencies?

23:18 dnolen: technomancy: here's the stack trace when I run lein deps

23:18 http://gist.github.com/246047

23:19 The-Kennz: Woho, I love lein-swank

23:19 technomancy: wow; crazy. I'll clear it out of my local repo and try again

23:19 dnolen: technomancy: should I do that as well?

23:19 technomancy: you could try it.

23:19 dnolen: like erase everything out of ~/.m2 ?

23:20 technomancy: erase whole directory or just the subdirectories?

23:20 technomancy: I can't repro. =\

23:20 ah: "Unable to store local copy of metadata"...

23:20 maybe it's just a permissions thing

23:20 try chowning and chmodding ~/.m2 first

23:22 dnolen: technomancy: yup permissions

23:22 thx

23:22 lein rulez

23:22 technomancy: cool; did you previously run lein as sudo or something?

23:23 dnolen: I probably did nonsensically at some point yes :P

23:23 technomancy: well if you're used to rubygems or something... =)

23:24 alexyk: I get an error in maven witrh clojure plugin, when it tries compiling a script which feeds fine into a repl: java.lang.Exception: Unable to resolve symbol: only in this context. Points to a line which is fine in repl, no actual symbol shown... is it normal?

23:24 dnolen: technomancy: yeah, Python also encourages the overly eager use of sudo.

23:25 technomancy: I started a wiki stub, is lein install necessary from the lein-swank directory at all?

23:25 or does it just get pulled in?

23:28 technomancy: dnolen: it should be able to pull it from coljars

23:28 *clojars

23:28 dnolen: technomancy: does lein swank work on the stable branch work, or do you have to be on the master branch?

23:29 alexyk: how do you replace the first space in a string by a T ?

23:30 arohner: alexyk: have you see clojure.contrib.str-utils2?

23:31 alexyk: arohner: not yet!

23:31 technomancy: dnolen: I think it might work on 0.5.0 but haven't tested it

23:32 alexyk: where's the standard docs for contrib? in fact, what do you guys have instead of javadoc/scaladoc? :)

23:34 the-kenny: alexyk: http://richhickey.github.com/clojure-contrib/index.html

23:34 alexyk: the-kenny: thx!

23:35 arohner: alexyk: there's also (doc function-name) and (find-doc string) from the repl

23:35 ,(doc map)

23:35 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

23:35 alexyk: so does clojure have thingies to generate API docs a ;a javadoc?

23:35 a la

23:35 a lá

23:36 cark: "à la" =)

23:36 arohner: or (find-doc "replace")

23:37 alexyk: cark: finally my wrong pattern is corrected by a Francophone! :)

23:38 cark: =)

23:38 alexyk: cark: or should I say a Walloon? :)

23:38 cark: indeed

23:40 alexyk: so how did rhickey generate those docs?

23:41 cark: you mean the docs from (doc some-function) ?

23:41 or a la javadoc ?

23:42 alexyk: cark: the docs on the website, http://richhickey.github.com/clojure-contrib/str-utils2-api.html -- or is it just a concatenation of the doc strings from the defn's?

23:42 arohner: alexyk: those are just the doc strings on the defns

23:43 alexyk: arohner: ok

23:43 arohner: and on the namespace

23:46 alexyk: how do I import just that replace from a repl, not from ns macro?

23:46 repl complains about: (use 'clojure.contrib.str-utils2 :only [replace])

23:48 The-Kennz: alexyk: alexyk There's already a replace in clojure.core

23:48 alexyk: and if I want to import str-utils2 as a whole, I get: repeat already refers to: #'clojure.core/repeat in namespace: user

23:48 is it predefined in core too?

23:48 The-Kennz: alexyk: You have to import like this: (use '[clojure.core.str-utils2 :as strut]) and use like this: (strut/replace ...)

23:49 KirinDave: The-Kennz: You mean require, right?

23:49 The-Kennz: alexyk: But that's mentioned in the doc for str-utils2

23:49 alexyk: ah ok

23:49 The-Kennz: KirinDave: Yes.. I always forget when I have to use which one ;)

23:50 alexyk: (require '[clojure.contrib.str-utils2 :as s]) says the doc

23:50 alexyk: btw, (doc clojure.contrib.str-utils2) is nil

23:51 The-Kennz: alexyk: doc prints the meta-description for a var, clojure.contrib.str-utils2 isn't a var

23:51 ,(doc doc)

23:51 clojurebot: "([name]); Prints documentation for a var or special form given its name"

23:51 alexyk: ah ok

23:53 so if I have a Java BitSet as state, do I have to wrap it in any refs or atoms?

23:55 tomoj: clojure concurrency won't help you there

23:56 alexyk: tomoj: I wonder if I need any by law :)

23:57 hiredman: alexyk: refs, atoms, agents, etc, are designed to hold immutable things

23:57 alexyk: what is defn- ?

23:57 notallama: private defn

23:57 alexyk: notallama: what's the private scope?

23:58 the-kenny: alexyk: Functions defined by defn- don't get exported from its namespace

23:58 tomoj: I suppose if you wanted to just have a bitset as state which gets replaced with an entirely new bitset but is never changed itself, you could use refs/etc

23:59 technomancy: dnolen: did you send that github message before you got everything sorted out?

23:59 * technomancy just noticed it

23:59 alexyk: tomoj: I need a map with millions of keys with small bitsets hanging off the leaves... The map may be worked in parallel, but the leaves must be updated atomically

Logging service provided by n01se.net