#clojure log - Jul 15 2009

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

0:02 grrrt: how can you test if a name is a function? I guess isa? or instance? wouldn't work here?

0:04 gnuvince: grrrt: fn? and ifn? come to mind

0:04 ,(fn? map)

0:04 clojurebot: true

0:04 grrrt: ahh doh!

0:04 sigh, brain has left the office for the day :)

0:04 gnuvince: ,[(fn? {}) (ifn? {})]

0:04 clojurebot: [false true]

0:04 grrrt: cheers

0:05 gnuvince: np

0:13 arohner: does anyone have experience running a profiler on clojure code in OSX?

0:13 or linux. but eclipse's TPTP is not working for me

2:29 Jomyoot: Is there example of how to structure clojure into different source files?

2:29 name spaces and etc?

2:29 basically a simple project structure

2:29 i so far have used clojure as glue code. so all in one file

3:25 ataggart: very loosely speaking, one clj file for a namespace

4:54 Jomyoot: should they use or require each other?

5:05 AWizzArd: depends on how you want to use them

5:06 both are valid options

5:06 I use 60% and require 40%

5:39 Jomyoot: is there a guilde or tutorial for this?

5:50 ataggart: with require you still need to use a namespace (or namespace aliias). with use you don't need to prefix everythign with a namespace

5:50 it's style prefernce more than anything

6:03 Jomyoot_: do i put deeper name spaces into deeper folders?

6:04 or throw all files into same folder

6:04 does java style folder/package mapping still work here?

6:06 jdz: the Java style hierarchical file/namespace relation remains

6:06 http://clojure.org/libs

6:08 Jomyoot_: any idea when cascade will be available?

6:09 jdz: what's cascade?

6:11 Jomyoot_: something tapestry guy said he would make

6:11 for clojure

6:11 that's all i know

6:11 Chousuke: Jomyoot_: you can also split a namespace into multiple files by having the "main" file use 'load to "include" other files

6:11 Jomyoot_: i don't even know if tapestry is popular

6:13 :use com.test.me.ns would that go look for the com/test/me/ns.clj file? assuming that it's all source file

6:13 Chousuke: yeah.

6:14 see (doc ns) and (doc require) at least.

6:14 the ns documentation is a bit scattered

7:36 Neun: hello, why does this not work: (eval (list #(%) "foo"))

7:36 why do I have to quote the function?

7:38 cemerick: Neun: is foo the function you're trying to invoke?

7:38 * cemerick is not sure what you're aiming for

7:39 Neun: I tried this (map (comp eval list) list-of-functions list-of-elemts)

7:40 this works though: (map #(%1 %2) list-of-functions list-of-elements)

7:40 cemerick: eval is unnecessary unless you've got symbols, etc., as opposed to actual functions

7:41 e.g.:

7:41 ,(eval '(+ 5 6))

7:41 clojurebot: DENIED

7:41 cemerick: bah

7:41 Neun: I see

7:41 cemerick: anyway, that would return 11, but clearly, you just want to invoke a fn directly:

7:42 ,(+ 5 6)

7:42 clojurebot: 11

7:42 jdz: Neun: would just plain (map apply list-of-functions list-of-elements) not work?

7:42 Neun: jdz: no, apply needs a vector of arguments

7:43 jdz: no, just a sequence

7:43 cemerick: Neun: not so:

7:43 jdz: well, not really

7:43 cemerick: ,(apply + (list 5 6))

7:43 clojurebot: 11

7:43 jdz: the last argument should be a sequnce

7:43 cemerick: right

7:43 ,(apply + 14 (list 5 6))

7:43 clojurebot: 25

7:44 jdz: ,(apply + 42)

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

7:47 Jomyoot: can (def x (ref (hash-map)) bedefined using (let) as well?

7:47 jdz: let creates bindings in it's scope. when the scope is gone, so are the bindings.

7:49 cemerick: Jomyoot: you can certainly use let to perform some initial computation, and use the result as the value of the new def binding: (def x (let [foo ... bar ...] (ref {baz (some-fn foo bar)})))

7:59 rottcodd: is there a way to call private functions in another namespace?

7:59 cemerick: rottcodd: (#'some.other.ns/fn-name ...)

8:00 #'foo returns the var named by foo

8:00 Chousuke: and var just happens to delegate to its value if it appears in operator position :P

8:01 cemerick: I think that was a stroke of genius. Much nicer than other lisps where you really had to be conscious of that sort of thing.

8:03 rottcodd: cemerick: thanks

8:10 rhickey: did anyone ever do a reasonable with-captured-bindings macro?

8:13 cemerick: ach, I always get tripped up by the order of fns to comp

8:14 rhickey: (foo (bar (baz ... -> (comp foo bar baz)

8:14 i.e. comp just removes some parens

8:15 cemerick: rhickey: yeah, I just happen to use -> more often, which applies in the reverse order

8:15 comp is more consistent with mathematical notation, too, so this is really just a mental problem on my part

8:15 rhickey: I have to think twice sometimes too :)

8:17 I really want to get a pipe macro in place, to further confuse things :), like -> but puts arg at end. We've discussed before, just need a name

8:18 saw an F# presentation where they did everything with the :> operator, made people very comfortable

8:18 cemerick: heh. I have no idea what :> would mean.

8:18 rhickey: sorry, |> operator

8:18 cemerick: yeah, that doesn't ring any bells, either :-)

8:19 Chouser: $ means end-of-the-thing in regex and sh

8:19 rhickey: right, I'm not advocating |>, but it had the same concept as pipe, put arg at end, except you have to keep repeating it

8:19 cemerick: ah

8:20 rhickey: we haven't used $ or | yet, probably not worth it for this

8:20 -<, <-

8:20 Chouser: ($-> coll (map foo) (filter bar))

8:20 cemerick: well, I generally try to avoid shell scripting, so #(-> % .. .. ..) and comp are good enough for me :-)

8:21 rhickey: cemerick: really, you use -> and wouldn't use (pipe xs (map f) (filter p) (reduce op)) ?

8:22 Chouser: One of the first clojure macros I ever wrote was called >>_

8:22 (>>_ coll (map foo _) (filter bar _))

8:22 rhickey: for pipe?

8:23 funny I would have gone the other way <<

8:23 maybe not

8:23 Chouser: it's going the same way as ->

8:23 rhickey: well, it's generally useful, and should be standard

8:24 Chouser: yeah, I used >>_ once or twice early on, but being non-standard makes it tiring to communitcate with others

8:24 rhickey: Chouser: yes, in some sense (calls) but not others (args)

8:24 Chouser: especially with a name like >>_ :)

8:24 cemerick: rhickey: Not sure I'd use it, at least until I'd had a chance to internalize it. -> is very intuitive for me, but so far, I'm feeling like I'd end up having to read the docs on pipe when I end up reading code later on.

8:24 Chouser: hmph

8:25 cemerick: Stuff like that changes fast, though.

8:25 Neun: jdz: maybe I could write (map apply seq-of-functions (map list (seq-of-values)))

8:25 wlr: what's wrong with calling it just, er, pipe?

8:26 cemerick: FWIW, I use -> most often for simple navigation of data structures (-> foo :key deref seq last), etc.

8:26 rhickey: wlr: nothing, except for the other meaning of pipe (data structure, IO channel)

8:26 cemerick: that's its intended use for sure

8:26 jdz: Neun: that should work.

8:27 rhickey: wlr: one reason -> isn't called 'thread'

8:27 cemerick: honestly, I'd be very worried if I were regularly mapping and filtering my way through things. Linear time bounds aren't nearly good enough. :-)

8:27 jdz: Neun: despite the fact that i don't like how it looks :/

8:28 Neun: jdz: yes, there should be something better/cleaner

8:28 rhickey: all of the seq fns are set up for pipe

8:28 wlr: rhickey: okay, competing concepts. thanks.

8:29 rhickey: anyway, we've got -<, <-, >>_, $-> - any others?

8:29 ->>

8:30 jdz: =>

8:30 Chouser: --> <--

8:30 jdz: ==>

8:30 cemerick: <- is the most intuitive of them all, at least with respect to ->

8:30 jdz: ^.^

8:30 but that's taken by meta

8:30 \m/

8:31 >.>

8:31 rhickey: I think Clojure datalog lib is using <- ?

8:32 cemerick: shouldn't it be (some-fn-name (filter f) (map f2) coll), though? By that I mean, shouldn't the collection be the last arg to the fn if it's proceeding right to left?

8:33 Chouser: but it's not proceeding right to left

8:33 that's why the left-pointing things may not be appropriate

8:33 cemerick: ah-ha -- that's what I get for reading a random group posting on "pipe"

8:33 Chouser: (map f2 (filter f coll))

8:34 rhickey: it's kind of imperative, take xs, map it, filter it, reduce it ...

8:35 In the F# demo it made people comfortable to see code that looked like "do this, do that", but was actually functional

8:36 I'm now with Chouser that call order dominates the sense of order, not arg order

8:36 so ->> or --> working best right now

8:37 Chouser: two > certainly stands out more than two -

8:37 -=>

8:37 rhickey: yup

8:37 Chouser: ->*

8:37 rhickey: = and > makes one think numbers

8:37 Chouser: >-

8:38 >>-

8:38 rhickey: Chouser: documenting the path to >>_, eh :)

8:38 Chouser: :-)

8:38 cemerick: multiple >'s make me think of bit-shifts

8:39 Chouser: >--

8:39 rhickey: cemerick: me too, but ->> still seems like an arrow to me

8:39 Chouser: (>-- coll (filter x) (map y))

8:39 rhickey: which is kind of nice in being able to call them the two arrow ops

8:40 arrow threads and double arrow pipes

8:40 through a series of calls

8:42 cemerick: of course, there's the inevitable clojure impl of haskell arrows :-P

9:01 weissj: is there a particular reason why there's no builtin function called != ? that just does (not (= a b))

9:02 Chousuke: there's not=

9:02 cemerick: ,(doc not=)

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

9:02 weissj: ah

9:02 cemerick: hrm, odd irc latency

9:02 weissj: would never have thought to look for that. :)

9:03 Chousuke: ! carries the "side-effect!" meaning

9:03 weissj: Chousuke: even when the ! is at the beginning?

9:03 cemerick: I would have exempted it for !=, but oh well

9:04 that's one of the advantages of having a BDFL (or similar), as opposed to cargo-cult design.

9:06 Jomyoot: do I have to both (require) and (refer) a namespace in another file?

9:06 jdz: or just use?

9:06 weissj: cemerick: what are bfdl and cargo-cult designs

9:07 cemerick: Jomyoot: yeah, just use use, or, require with an :as name: (require [some.ns.util :as util]), and then access some.ns.util's fns with util/fn-name

9:08 Chousuke: require needs its argument quoted though :)

9:08 or you can use the ns macro

9:09 Jomyoot: So (refer) without (require) does not work?

9:09 Chousuke: I've never used refer directly :/

9:10 jdz: refer with require is called 'use', as far as i understand

9:10 cemerick: weissj: http://en.wikipedia.org/wiki/BDFL -- by cargo-cult, I meant a bikeshed-susceptible design process (http://bikeshed.com/)

9:10 jdz: and refer does work without require. see the documentation what refer does...

9:11 Jomyoot: I get java.lang.ClassNotFoundException: com.atcloud.build-tags-hash-map

9:12 I have (ns com.atcloud

9:12 (:use [clojure.contrib.sql]))

9:12 and (defn build-tags-hash-map [db] in the other file

9:12 jdz: do you have a file com/atcloud/build_tags_hash_map.clj in your classpath?

9:13 Jomyoot: i am idiot

9:13 i am supposed to use /

9:13 rather than . i think

9:15 weissj: is it possible that a future version of clojure will allow you to have a function call earlier in the file than its definition? or is there something too inherent in the language that disallows this?

9:15 it's not a huge deal, but it tends to make a file harder to read (the higher level more 'important' stuff is at the bottom)

9:16 cemerick: weissj: I think rhickey has said that it's possible that forward declarations could eventually be handled automatically

9:16 weissj: cemerick: cool

9:16 cemerick: until then, you can use declare to create those (undefined) vars, and then define them later in the file

9:17 weissj: cemerick: functions too?

9:17 cemerick: especially functions

9:17 IME, anyway

9:17 weissj: hm, i'm not sure if that makes things better or worse :)

9:17 cemerick: well, it lets you structure your code how you want, anyway

9:18 weissj: cemerick: yeah, but you still have declarations at the top

9:18 cemerick: it generally doesn't happen that much, at least to me

9:18 *shrug*

9:18 weissj: oh i see you can declare them all at once? nice

9:18 ie (declare a b c d)

9:19 rhickey: cemerick: I don't know that I said that - it would be a change to the compilation model (from the equivalent of streaming the same commands into a repl), and would require the introduction of some notion of compilation unit, issues with macros etc

9:19 rottcodd: should I use *var* or var for variable names?

9:19 jdz: rottcodd: "variables" is a very stretched term

9:20 rhickey: rottcodd: *var* only if you intend to dynamically rebind them

9:20 cemerick: rhickey: it was a long time ago (probably two April's ago or so), when I had the same question as weissj. I wouldn't be surprised if things have changed since then that would make it less feasible.

9:20 regardless, it's surely a lot of work for a very small gain, IMO

9:20 rhickey: cemerick: it is certainly possible, but a lot of work for a very minor feature IMO

9:20 heh

9:20 Chouser: I find code easier to read when I know where to find definitions, that is "above here". Declaring things out of order doesn't seem like an improvment to me.

9:22 weissj: Chouser: yeah i don't think it's a big deal either, i am just used to java where i put all my private and protected methods at the bottom

9:22 rhickey: what old time Lispers really want is not whole-file resolution, but simply the ability to compile with unresolved names and get runtime errors

9:22 cemerick: old-time *common* lispers, of course. The current situation in clojure is exactly like the schemes I remember.

9:23 rhickey: cemerick: yes, CL

9:24 there's the whole 'define your program in the debugger' thing

9:24 cemerick: rhickey: did you notice the type hinting that C. Nutter is adding to JRuby?

9:24 rhickey: cemerick: link?

9:26 cemerick: rhickey: http://twitter.com/headius/status/2639903017 http://twitter.com/headius/status/2640249841 http://twitter.com/headius/status/2640406401

9:28 rhickey: cemerick: java with 'end' ?

9:28 cemerick: ouch :-)

9:29 rhickey: I've said the same thing as far as Clojure becoming Java with parens

9:29 what's the point?

9:29 cemerick: either are surely better than Java -- if the hints are just there to keep the reflector away, then all's well

9:31 rhickey: it's telling that, honestly, most devs don't need much more than Java -- so, giving them the opportunity to write java-ish things in one's language makes adoption *possible*, anyway. And not ensuring smooth interop along all possible axes makes widespread adoption simply impossible.

9:31 rhickey: cemerick: I'm not sure, vs a Java stub and a simple way to reach more involved logic in the preferred lang. The cost is bringin in all the Java cruft into your lang, protected etc

9:34 cemerick: rhickey: Oh, I agree wholeheartedly, but then, I'm not involved in building or using a language for the masses.

9:34 rhickey: Have you ever seen LinJ?

9:34 seems to have disappeared, but it was a lisp that generated idiomatic Java

9:35 was weighed down, IMO, by the need to support all Javaisms

9:36 cemerick: its page on cl-user.net has a pretty meager example, but yeah, I can definitely see how dragging all that cruft along would make a lot of things painful

9:36 weissj: if I have a java method i want to call that can either return a value or throw an exception, and i want to catch the exception, or store the return val in a variable, how do i do this? declare the var as nil first?

9:36 rhickey: after all, if a lang Y is to support all constructs of another lang X, is it not inherently going to be more complex than X?

9:36 cemerick: type-hinting is pretty painful as it is, but it's certainly necessary

9:37 Chousuke: weissj: wrap the java method call in a function

9:37 cemerick: (although I wonder if the JIT in JDK 7 with all of its reflection-inlining, etc would optimize a reflective call to a regular method invocation given enough heat)

9:37 Chouser: weissj: (let [foo (try (foo-fn) (catch Exception e "error-val"))] ...)

9:38 weissj: Chouser: i see thanks

9:38 Chouser: that is, the final value of the catch block is what 'try' returns on the exception case

9:39 weissj: Chouser: yeah in my case i'm later checking for nil, so i'll have the exception clause return nil. that'll do it!

9:41 Jomyoot: is lisp code supposed to be more managable?

9:41 than JAVA?

9:42 once you have lots of it?

9:42 rhickey: so, last call, I'm thinking about calling 'pipe' ->>

9:43 Chousuke: Jomyoot: that probably depends on how good you're at writing manageable lisp code :)

9:44 Jomyoot: But lisp has more powerful tools for abstraction than java IMO, so I'd say yes.

9:45 cemerick: If you know what you're doing, there's amazing power in a good lisp. If you're not a good programmer, then you'll be hopelessly lost.

9:46 I'm a little of both, but I've aspirations. :-)

9:51 weissj: is there a builtin function to execute a command on the command line (perhaps via java's Runtime/Process/execute api)

9:53 Jomyoot: so using .java stuff does break immutablity

9:53 weissj: clojure.contrib.shell-out/sh - found it. doc search on execute found nothing, but 'exec' found this

9:53 Jomyoot: i can modify their state without dosync

9:54 yason: Hmmm, was there a byte stream as a lazy sequence akin to line-seq ?

9:54 cemerick: Jomyoot: you can break immutability in a variety of ways if you're really motivated and your data structures allow it.

9:55 Jomyoot: what's the point of dosync when it's so easy to break immutability when using java objects

9:56 Chousuke: the point is that when you do use the immutable data structures, it allows for easy concurrency

9:56 Clojure does not force immutability on you. It just gets harder and harder to keep your program working the more mutability you introduce

9:57 cemerick: it's pretty difficult to introduce mutability to begin with, if you stay within clojure.

9:57 Chousuke: mutability support is pretty much an interop thing.

9:57 Jomyoot: it is hard to write Clojure without using java interop though

9:58 cemerick: Jomyoot: a corollary would be, "what's the point of garbage collection and memory protection in Java if it's so easy to segfault when you call into native methods?"

9:58 yason: Jomyoot: depends. I don't know Java much so I tend to steer away from any Java interop automatically

9:58 Chousuke: Hmm, perhaps.

9:58 Jomyoot: i get your point

9:58 cemerick: Jomyoot: Depends on your domain. I touch java very rarely.

9:58 yason: Jomyoot: I just wrap the most essential java stuff to get my stuff running (file i/o or GUI stuff) and stay with Clojure then

9:59 Chousuke: proper use of java interop is to keep it isolate from pure, functional clojure logic :)

9:59 isolated*

9:59 yason: Chousuke: that's what I was trying to say, with too many copies of "stuff" :D

10:00 Chousuke: of course, some java stuff is "immutable" as well, like strings, and thus not a problem.

10:01 It seems that arrays are the worst troublemakers :/

10:35 Jomyoot: Is emacs still pretty as IDE for Clojure?

10:38 weissj: anybody here known about ant tasks with lancet? (lancet/echo {:message "hi" :level "warning"}) gives java.lang.ClassCastException: Cannot cast java.lang.String to org.apache.tools.ant.taskdefs.Echo$EchoLevel

10:39 ant actually takes a string for :level, but here it seems to insist on an internal class called "EchoLevel"

10:39 shoover: Jomyoot: I'm not sure anyone has ever accused emacs of being pretty, for clojure or otherwise

10:39 useful, sure

10:42 Jomyoot: What is equivalence of simple hash in Ruby like this { :a => 1, :b => 2, :c => 3} is that HashMap in Clojure then?

10:43 Chouser: Jomyoot: {:a 1, :b 2, :c 3} is a map in Clojure

10:44 scgilardi: Jomyoot: and literal maps are hashmaps

10:45 Jomyoot: is 'a equivalence of :a in ruby?

10:46 arbscht: it's probably not wise to think in terms of direct equivalents

10:46 liebke: jomyoot, :a in ruby is equivalent to :a in Clojure

11:00 weissj: once i delete a function definition in a file, and load it into the repl, how do i remove the binding from the repl?

11:01 do i have to restart the repl?

11:01 (in other words i remove the function def 'myfunc' but the repl still sees it as defined and I don't want it to be)

11:01 Chousuke: you can either redefine the var to nil or something or use ns-unmap

11:02 it's pretty simple to write a function that "cleans out" a namespace

11:04 weissj: ok, i think i got that

11:05 what's wrong with (ns myns (use lancet (:as 'ant)))

11:05 java.lang.IllegalArgumentException: No value supplied for key: true (jonSuite.clj:1)

11:06 Chouser: (ns myns (:use [lancet :as ant]))

11:06 except lancet probably needs to be longer

11:07 weissj: longer?

11:07 Chouser: should be the fully-qualified namespace name

11:07 Halloway didn't call it just "lancet", did he?

11:07 scgilardi: and :as is more often associated with :require. with use, you're bringing all of lancet's names into the current namespace and then also allowing prefixing them with ant/

11:07 Chouser: good point!

11:08 (ns myns (:use [lancet :as ant :only []]))

11:08 weissj: wait, i just want to refer to functions in lancet with the name ant instead

11:08 not also bring in everything into my own ns

11:08 Chouser: right.

11:08 so :only []

11:08 weissj: ok

11:09 scgilardi: chouser's most recent example is how I would write that

11:09 Chouser: or you could use 'require' instead, but these days I don't usually recommend that

11:09 I'm still hoping to see those two merged at some point

11:09 scgilardi: me too

11:11 cemerick: Chouser: you don't like require + :as?

11:12 Chouser: cemerick: it's fine until you decide there's one var you want to refer in

11:12 so you had (:require [fully.foo :as foo])

11:12 and now you have to change it to (:use [fully.foo :as foo :only [bar]])

11:13 weissj: Chouser: halloway did just call it 'lancet', btw

11:13 cemerick: so you prefer :use + :as + :only?

11:14 scgilardi: did we come up with any downsides to (:use fully.foo :as foo) implying :only [] unless explicitly overridden?

11:14 Chouser: cemerick: at least it's more consistent -- that way I don't end up with a block of :requires and a block of :uses and have to reorder things based on which ones need an :only

11:15 cemerick: yeah, that's a point

11:15 Chouser: scgilardi: breaking change is a downside

11:15 Chousuke: Chouser: couldn't you add a :refer after the require?

11:15 cemerick: scgilardi: as long as there is an escape hatch to get full use (a wildcard :only, essentially). I don't do that very often at all, but when I do, it's pretty necessary to retain sanity.

11:16 Chouser: Chousuke: is :refer supported by something?

11:16 scgilardi: cemerick: the escape hatch is :exclude []

11:16 cemerick: ok :-)

11:16 Chousuke: (ns something (:require [foo.bar :as foo]) (:refer foo.bar :only [some stuff here]))

11:16 Chouser: the ns macro?

11:16 Chouser: Chousuke: ah. I guess that might work, though 'ns' doesn't document it.

11:17 I'd rather have the namespace listed once anyway.

11:17 Chousuke: is there something wrong with :use + :only ?

11:17 Chousuke: Chouser: not really.

11:17 I guess it's a matter of preference

11:18 scgilardi: chouser: I find it a little ugly (though I still use it). It's like explicitly passing nil as an argument to a function. It kinda feels like it would be nicer if you didn't have to.

11:18 Chousuke: I guess the combined effect of :as and :only is a bit confusing, too

11:18 Chouser: scgilardi: yes!

11:19 Chousuke: you wouldn't expect the entire namespace to be available through the :as alias either.

11:19 Chouser: scgilardi: I find it ugly, but less painful than mixing both :use and :require in random ways in the same ns form

11:19 Chousuke: I wonder if ns actually does support :refer

11:19 Chouser: Chousuke: good point. maybe :only is misnamed for :use.

11:19 Chousuke: (doc refer) ; refers to it though :P

11:19 clojurebot: "([ns-sym & filters]); refers to all public vars of ns, subject to filters. filters can include at most one each of: :exclude list-of-symbols :only list-of-symbols :rename map-of-fromsymbol-tosymbol For each public interned var in the namespace named by the symbol, adds a mapping from the name of the var to the var to the current namespace. Throws an exception if name is already mapped to something else in the current nam

11:20 Chousuke: damn, too lon

11:20 g

11:20 Chouser: Chousuke: ns macro currently just maps the keywords (like :use and :require) to core function names, and calls them.

11:20 scgilardi: chouser: exactly right. I think the combination of :use and :as as we have things now is just an attractive hazard. Better replaced by useful functionality.

11:20 Chousuke: oh wait.

11:20 refer actually refers to :use, not :refer

11:20 * Chousuke wonders about his subconscious filter

11:21 Chousuke: hmm...

11:25 Chouser: so the least-breaking way forward would be to introduce a new word and give it the semantics we now know we want

11:25 and deprecate :use and :require

11:25 scgilardi: chouser: I think Rich also had a notion of "default aliases" at one point. Removing :require and replacing it with :use :as would tend to thwart that.

11:26 Chouser: but using up another word has drawbacks too

11:26 Chousuke: Chouser: :assimilate? :)

11:26 Chouser: scgilardi: hm... maybe.

11:26 :demand

11:26 :-P

11:26 scgilardi: :depend

11:26 Chouser: actually -- hm. :require doesn't do anything bad, it's just missing features. Maybe that's the way forward.

11:27 scgilardi: what's it missing?

11:27 Chouser: perhaps we could add :refer and support for default aliases to :require

11:27 then deprecate :use

11:33 scgilardi: as a detail of the current implementation (:require [clojure.contrib.sql :use true]) is exactly equivalent to (:use clojure.contrib.sql).

11:34 cemerick: oh, poor Stuart :-)

11:34 Chouser: oh, does :only work with :require?

11:35 scgilardi: only when accompanied by ":use true" (but that could be changed pretty easily, I think)

11:36 Chouser: oh, I see.

11:36 scgilardi: sounds pretty nice... add support for the refer options to :require and have them imply :use true (effectively)

11:37 Chouser: probably still need something that means :exclude, or at least :exclude []

11:38 so as to enable our lazy brethren

11:38 :refer-all-because-i-care-more-about-myself-than-my-readers

11:39 cemerick: Chouser: there *are* good reasons, aside from sloth

11:39 Chouser: cemerick: really?

11:39 in cases where :as z or something wouldn't suffice?

11:40 cemerick: well, a throwaway :as name is just noise.

11:40 I use use in conjunction with two namespaces that provide a pile of utility fns that we use throughout our codebase.

11:42 e.g. stuff that, in our domain, we'd be perfectly happy if it happened to be defined in clojure.core (but obviously won't ever, and shouldn't be)

11:44 Chouser: hm

11:44 ok, would you buy :refer :all ?

11:45 cemerick: what, (:require [foo.bar :refer :all])?

11:45 Chouser: yeah

11:45 cemerick: fine by me

11:46 It's definitely a corner case, so I'm happy to accept a syntactic compromise in order to make everything else simpler.

11:50 scgilardi: :exclude is one of the refer options to support. We could add :refer :all as sugar for :exclude [], but we would already have the capability it provides.

11:51 the full list is :exclude, :only, and :rename

11:52 Chouser: but if :only is renamed to :refer (which I like very much) that raises the question of what :exclude and :rename should be called

11:52 :refer-all-but for :exclude?

11:53 scgilardi: I think :only :exclude and :rename fit just as nicely with the word "require" as they do with the word "refer". Why rename :only to :refer?

11:55 Chouser: because require is a verb whose subject is the lib. "only" doesn't modify the lib, but something else, so it seems a poor fit to me. "refer" is a verb matching the core fn, so seems a natural choice.

11:56 duck1123: I always mess up :exclude as :except

11:58 scgilardi: I see it as "require this collection of stuff" (which is the lib). The modifiers let us optionally tailor which pieces of the collection we also bring into the namespace. I do see your point though, we are pulling in the entire lib either way and these options are about how that impacts the current namespace.

11:59 Chouser: on the other hand I care so much less about the name than the functionality. :-)

12:02 scgilardi: with either the current or the new names, this would be an easy change to get right in the implementation and would strictly add capability to require that nobody is using currently. it would leave us free to deprecate :use.

12:08 weissj: if i want to create a java object, call a setter on that object, then return the object, do i need a var?

12:10 Chouser: nope

12:10 not even a local, if you use 'doto'

12:10 (doto (new JavaClass) (.setFoo 5))

12:13 rhickey: Chouser, scgilardi: It would be nice if this new improved use/require thingy had a completely new name, and vastly simpler syntax and semantics than use/require currently do, i.e. if you pick a new name, even :uses, you get a clean slate for a simpler design

12:13 I can never remember how to use use and require

12:13 Chousuke: heh.

12:19 scgilardi: I'm open to suggestions. Other than collapsing both use and require into one thing, I don't see obvious opportunities for vast simplification.

12:20 rhickey: scgilardi: doing less is an opportunity

12:20 the use of the nested vector is tricky too

12:22 scgilardi: please explain re: doing less

12:24 rhickey: well, I haven't thought it through, but right now it is undeniably complex, so it begs the question what would be simpler? where is there redundancy? what is infrequently used?

12:25 e.g. foo.bar.baz vs (foo.bar baz) seems like a feature but adds complexity

12:26 scgilardi: removing the opportunity to use prefix lists to extract out common prefixes would lead to simpler, but more redundant ns forms.

12:27 rhickey: scgilardi: I thought we'd go the other way

12:28 having just :uses vs :require and :use is good in and of itself

12:28 the nested structure is also tricky

12:29 I can't design it right now, just encouraging a search for simplification

12:29 scgilardi: that sounds like a good direction. we could remove the vectors perhaps by recognizing symbols as distinct from keyword value pairs in the same way that clojure cond is simpler than CL cond.

12:29 ok, I'll give it some thought

12:30 Chouser: if we only allow (foo bar) instead of foo.bar, would it be acceptible to remove one nesting level? (:uses (foo bar :as fr baz :as fz)) ?

12:30 eh

12:30 nm, I don't like that

12:31 scgilardi: Along the lines of the "circular load" issue, I'm giving some thought to a design for removing the need for :reload and :reload-all by using the resource mod dates like the compiler does.

12:31 rhickey: scgilardi: sounds appealing

12:32 scgilardi: rhickey: I'll write up what I have and post it to the developer's list.

12:32 rhickey: scgilardi: thanks!

12:33 scgilardi: chouser: what if "fr baz :as fz" were on a separate line. That kind of construct is what I was talking about for removing the vectors above.

12:34 rhickey: commas are free too

12:34 (:uses (foo bar :as fr, baz :as fz)

12:35 ignored but useful still

12:37 (:uses (foo bar {:as fr} baz {:as fz :refer bleh}))

12:39 nice because adding options doesn't require restructuring

12:39 Chousuke: I don't see the point of "foo bar" instead of foo.bar

12:39 or is it importing two libraries? :/

12:39 rhickey: right 2

12:40 share prefix

12:40 cemerick: where's the prefix, then?

12:40 scgilardi: For simplifying, I like them being inline better than collected in maps. Adding option wouldn't require restructuring in that case either. A keyword implies a subsequent value.

12:40 rhickey: cemerick: foo.bar and foo.baz

12:40 cemerick: ah.

12:41 rhickey: scgilardi: but a lot harder to parse, even with commas

12:41 better with newlines

12:41 scgilardi: but compare: (:uses (foo [bar :as fr] [baz :as fz :refer bleh]))

12:42 rhickey: scgilardi: I really dislike that because the two names are at different nesting levels when no options

12:42 (:uses (foo bar [baz :as fz :refer bleh]))

12:43 ick^

12:43 scgilardi: ok, I understand that

12:44 rhickey: saving typing is a non-objective here, we want clarity and somewhat guessable syntax

12:45 Chousuke: I like the map approach.

12:46 rhickey: maps might be a little easier on tools, they definitely are parsing this ns stuff right now, with a lot of hair-pulling

12:48 scgilardi: I don't mind maps. There is a tension between regularity and succinctness though. I trust we don't want to see empty maps when there are no options.

12:48 absolutely regular: (prefix name opts name opts name opts)

12:49 Chousuke: well, '(' prefix (lib-name option-map?)+ ')' would still be very simple

12:50 scgilardi: I agree. I think we should remove the limitation that lib-name can't have any dots in it. I'd like to be able to express (:uses (clojure.contrib sql sql.test)) without requiring two :uses clauses.

12:51 Also, if we do end up with :uses, we could also change to :imports and break the (perhaps) unfortunate one to one mapping between ns keywords and like-named functions.

12:51 ns being declarative in English as well as intent would be a plus I think

12:53 * cemerick gets worried when alignment with natural language comes up in any programming context

12:54 * rhickey worries when alignment with natural language fails to come up in programming naming discussions :)

12:55 Chousuke: Why aren't dots allowed in lib names currently, anyway?

12:55 cemerick: rhickey: surely I don't have to point you towards AppleScript :-P

12:55 besides, this isn't about naming at all, is it?

12:55 Chousuke: cemerick: what applescript does is called "taking it too far"

12:55 cemerick: it's still important :)

12:56 rhickey: cemerick: it's both, use vs uses is naming, the structural stuff is not

13:39 krl: anyone using clojure with sesame?

13:40 jackdempsey: no, but sounds delicious

13:41 duck11231: I hadn't tried sesame, but i did some work with jena

13:41 until I abandoned it to go a different way

13:41 krl: i need a good rdf store without coding java. :)

13:43 duck11231: I found that I liked Jena better as a RDF store when I was evaluating both

13:43 plus, jena worked better with Topbraid Composer.

13:43 weissj: can someone tell me what's wrong with this (trying to process xml): (clojure.contrib.zip-filter.xml/xml-> myxml :entry)

13:43 1:48 jon-install=> java.lang.ClassNotFoundException: clojure.contrib.zip-filter.xml (repl-1:47)

13:44 i need slashes?

13:44 krl: duck11231: what was better with jena?

13:44 Chousuke: weissj: that looks fine

13:45 duck11231: It's been so long since I looked at the two. I think I needed inferencing that sesame wouldn't give me right

13:45 plus Jena was easier for me to learn

13:45 weissj: Chousuke: do you know why i'm getting the ClassNotFoundException? isn't that code supposed to be in the contrib jar?

13:45 Chousuke: weissj: you probably need to require it

13:46 weissj: using the fully-qualified name to get to unimported stuff only works with java.

13:46 weissj: Chousuke: ah

13:48 Chousuke: (require 'clojure.contrib.zip-filter.xml) ?

13:48 Chousuke: yeah.

13:48 duck11231: Chousuke: really? I could've sworn I've done something like that and it worked. (although it may have been required in a different ns)

13:48 weissj: (xml-> myxml :entry)

13:48 1:54 jon-install=> java.lang.Exception: Unable to resolve symbol: xml-> in this context (repl-1:53)

13:48 Chousuke: weissj: require is not use.

13:48 weissj: after requiring, you can use the fully-qualified name :)

13:49 weissj: oh

13:49 Chousuke: alternatively, (require '[clojure.contrib... :as xml]

13:49 )

13:49 and then (xml/xml-> ...)

14:19 weissj: ok, so i see how to parse xml with zip_filter/xml, but how do i edit the structure? ie, i found the element and want to replace it with something else

14:20 Chouser: weissj: use the functions in clojure.zip

14:25 weissj: Chouser: i see there's a zip/replace... but not sure how to use that. is there an example somewhere of finding something in xml and replacing with something else

14:28 Chouser: http://paste.lisp.org/display/71471

14:29 weissj: Chouser: thanks!

14:30 Chouser: if you think you might ever need to change more than one item found by a filter (ie. changing every <b> tag or something), zip-filter is going to let you down

14:31 in that case (and perhaps in every case) I'd recommend you look at enlive

14:42 weissj: Chouser: for my purposes right now, i'm doing one edit at a time. having trouble figuring out how to replace the value of an attribute tho

14:48 cemerick: am I right in thinking that there's no var I can bind to prevent the runaway printing of circular datastructures?

14:48 * cemerick waits for the 'patch welcome' response ;-)

14:49 Chouser: *print-level*

14:49 ,(doc *print-level*)

14:49 clojurebot: "; *print-level* controls how many levels deep the printer will print nested objects. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum level to print. Each argument to print is at level 0; if an argument is a collection, its items are at level 1; and so on. If an object is a collection and is at a level greater than or equal to the value bound to *print-l

14:51 cemerick: yeah, that I know about -- I was hoping to retain unlimited print-level and print IDs or something for recursively-referenced objects

14:51 Chouser: oh, you mean for IDerefs in particular

14:51 cemerick: yeah

14:52 though it's a general problem for anyone writing a print-method or print-dup impl for, say, a regular Java class

14:52 Chouser: or even .toString

14:52 cemerick: yeah

14:53 Chouser: then even *print-level* doesn't help

14:54 cemerick: I guess I'm looking for something like #1={:foo #1#}

14:54 Chouser: oh. my.

14:55 I guess that's not unreasonable. Does pprint do something like that?

14:55 cemerick: hrm, that's an idea

14:55 Chouser: ,(let [x (java.util.HashMap.) y (java.util.HashMap.)] (.put x :y y) (.put y :x x) (.toString x))

14:55 clojurebot: java.lang.StackOverflowError

14:57 cemerick: nope, pprint doesn't help -- although it looks like the beginnings of an impl of that sort of thing is in pprint/dispatch

14:59 Chouser: hm, this shouldn't be hard

14:59 cemerick: no, one just needs to track the objects that have been visited so far

15:00 Chouser: IDerefs in particular

15:00 ids are already printed

15:01 cemerick: yeah, that'd be the first target -- general support for any circular references in java objs would be a little trickier, though a general facility that any implementor of a print-method or print-dup method would be handy

15:03 Chouser: but the latter is impossible

15:03 isn't it? that's what the java.util.HashMap example above shows

15:04 print-method doesn't even get touched

15:04 cemerick: hrm

15:05 there's a print-dup impl for java.util.Map, but not for print-method

15:06 Chouser: oh, overridding .toString. hm.

15:07 cemerick: so, I don't think it's reasonable to think all java classes could be covered, but standard collections seems reasonable, and whatever mechanism is used to track visited objects for IDerefs and standard collections could be reused for any other print-method impl

15:07 Making this work with print-dup would require reader changes, of course.

15:07 or, no, they wouldn't, nm

15:08 lisppaste8: Chouser pasted "prevent infinite print recursion for IDeref" at http://paste.lisp.org/display/83647

15:13 cemerick: Chouser: ech, I'm still on v1.0, no future?

15:13 That looks about right, though

15:15 Chouser: oh, just take that part out

15:16 lisppaste8: Chouser annotated #83647 "without 'future' support" at http://paste.lisp.org/display/83647#1

15:22 cemerick: it works on a trivial example, but I'm still getting spews from real data. I'm trying to isolate the issue.

15:23 Chouser: hm...

15:23 actually, binding anew at each level isn't quite what I had in mind originally

15:26 cemerick: hrm, actually, I think that might be a bug on my part

15:26 (unsuprisingly)

15:28 ChrisPS: ...

15:28 Chouser: huh. no way to find out if a var has been bound thread-locally except to attempt a 'set!' and catch the exception if not?

15:30 cemerick: Chouser: Var.getThreadBinding, but it's package-private

15:30 Chouser: right

15:34 lisppaste8: Chouser annotated #83647 "manual binding scope, without future" at http://paste.lisp.org/display/83647#2

16:05 porpoise: I made some change to a file and did (use 'mycode.myfile) and it gave me the same error as before I fixed my file. How do I get it to reload the file with the changes?

16:05 when I restarted clojure it worked fine

16:06 Chouser: (use :reload 'mycode.myfile)

16:06 porpoise: oh

16:06 heh thanks

16:06 maybe I should keep a noob journal and write a noob guide

16:06 i'm asking enough dumb questions

16:07 Chouser: http://clojure-log.n01se.net/ is my noob guide

16:07 a bit wordy, I suppose

16:07 porpoise: cool

16:10 technomancy: porpoise: it's easier if you have editor integration

16:10 porpoise: technomancy: I'm using slime and emacs

16:10 is there a better integrated editor for clojure?

16:11 I was doing C-c C-l before

16:11 technomancy: porpoise: if you've already got slime set up, just use C-c C-k

16:11 or that

16:11 porpoise: C-c C-l didn't solve my problem but (reload ...) did

16:11 technomancy: did you do C-c C-l on the file that actually changed?

16:12 porpoise: technomancy: yes. and it prompted me whether to save and I said yes

16:12 so I thought it was weird that it didn't actually reload

16:12 technomancy: that's really strange

16:12 porpoise: maybe my setup is screwed up

16:13 does it work properly for you then?

16:13 technomancy: do you only have one slime instance running?

16:13 yeah, I've never had that problem

16:13 porpoise: technomancy: I'll restart emacs to check

16:13 technomancy: if you can consistently reproduce it, please submit it as a bug to the clojure mailing list

16:13 bonus points if you can narrow it down to a simple case

16:15 porpoise: maybe i'll try it on clojurebox on my windows machine as well

16:15 what instructions should I use to setup slime and clojure? I used

16:15 the Bill Clementson script

16:15 technomancy: clojurebot: slime?

16:15 clojurebot: slime is best configured using M-x clojure-install once you have clojure-mode installed. Please *don't* configure it manually unless you know what you're doing.

16:16 technomancy: hrm; I personally heartily recommend the instructions at http://technomancy.us/126 while fully admitting that I may be biased.

16:16 Bill Clementson's stuff is pretty outdated.

16:17 Chouser: what's do you call the class in which a nested class is nested?

16:17 not its parent class

16:17 its "nestor class"

16:17 j-dot: outer class?

16:17 technomancy: container?

16:17 cemerick: outer class, usually

16:17 Chouser: ah, thanks

16:17 porpoise: the nest?

16:18 cemerick: is anyone aware of a NetBeans RCP wrapper for clojure (or the start of one)?

16:19 weissj: Chouser: any hints on how to replace an xml attribute value? (xml-> z zf/descendants :foo (attr :name))

16:19 ("hi")

16:19 it just returns the value, not the whole attribute. if i try to replace it with "yo" like so:

16:20 (zip/replace rpl (parse-str "yo"))

16:20 1:40 user=> org.xml.sax.SAXParseException: Content is not allowed in prolog. (repl-1:39)

16:20 Chousuke: tried with just "yo" instead of trying to parse it?

16:20 Chouser: Yeah, the attributes aren't children in xml-zip

16:21 hiredman: lisppaste8: url?

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

16:21 Chouser: you'll probably have to replace the whole element

16:22 weissj: Chouser: how can i replace the whole element, if i only know one attribute

16:22 Chouser: you'll have to not go down that far in your filter expr

16:23 weissj: Chouser: is there a way to select the element based on its attribute?

16:23 Chouser: yes

16:24 you know the value you want, or just the existence of the attr?

16:24 weissj: Chouser: value

16:24 (xml-> z zf/descendants :foo [(attr= :name "hi")])

16:24 Chouser: right

16:24 weissj: that seems to select a lot more than the element

16:25 lisppaste8: hiredman pasted "get non-public field" at http://paste.lisp.org/display/83651

16:26 hiredman: ugh

16:26 missing a paren

16:26 Chousuke: I like the name :P

16:26 hiredman: :)

16:27 beutdeuce: question, how do you do if-else statements?

16:27 Chouser: weissj: it's a loc object

16:27 weissj: Chouser: oh ok.. let me see if that works

16:28 Chousuke: beutdeuce: (if condition then-expr else-expr)

16:28 beutdeuce: see also: cond, when, if-let, condp

16:29 beutdeuce: k

16:29 weissj: Chouser: so what do i give as the 2nd arg to zip/replace, if i'm replacing <foo name='hi'>1</foo> with <foo name='yo'>1</foo> ? i can't just use that string because that code won't know the rest of that element, ie, the "1" content.

16:29 Chouser: (def changed (let [e (xml1-> z zf/descendants :foo [(attr= :name "name1")])] (zip/replace e (assoc-in (zip/node e) [:attrs :name] "new-name"))))

16:30 so beautiful and simple :-P

16:30 why can't I annotate that paste? too old?

16:30 beutdeuce: why doesnt this work => http://clojure.pastebin.com/m478e6cc

16:30 weissj: Chouser: yeah i seem to be giving up a lot to get thread safety when i don't need it :)

16:31 Chouser: the APIs just need work

16:31 I have faith

16:31 :-)

16:32 Chousuke: beutdeuce: the then and else are not part of if syntax

16:32 beutdeuce: oh

16:32 k

16:32 Chousuke: beutdeuce: also, you should not put the closing parens on their own lines

16:33 they'll feel lonely.

16:33 beutdeuce: now, it tells me too little arguments for if

16:33 technomancy: Chousuke: that's the best reason I've heard yet. =)

16:33 weissj: beutdeuce: you need two forms, a "then" and "else" form

16:33 if you're just doing an "if" with no "else", use when

16:34 beutdeuce: k

16:34 argh, still too few arguments => http://clojure.pastebin.com/m6c8cfe87

16:35 weissj: beutdeuce: there's no "then" or "else" -

16:35 beutdeuce: yes there is

16:35 weissj: there shouldn't be

16:35 example:

16:35 beutdeuce: oh

16:35 technomancy: also the "then" and "else" clauses need to be *inside* the last paren of the "if" clause

16:36 weissj: (if (= (+ 1 1) 2) (print "yep") (print "nope"))

16:36 beutdeuce: yeah, k , thnx

16:36 Chouser: ,(if (= (+ 1 1) 2) (print "yep") (print "nope"))

16:36 clojurebot: yep

16:37 beutdeuce: does clojure do null or nil ?

16:37 Chousuke: nil

16:37 which equals java's null

16:37 beutdeuce: k

16:39 Chousuke: technomancy: If you want more rational reasons, I guess it reduces visual noise because lisp code tends to nest a lot; or that generally every nesting level will only have only one expression

16:39 technomancy: Chousuke: yeah, but many people don't buy that right away

16:40 porpoise: technomancy: I'm not using the emacs starter kit because I already have an Emacs setup (based on the launchpad apt-source). It seems slime is not part of ELPA? Should I just install slime manually?

16:40 technomancy: porpoise: clojure-mode can handle that for you actually with M-x clojure-install

16:41 porpoise: oh

16:42 Chousuke: I set myself up a super-emacs (moved away from aquamacs to Cocoa emacs) using http://github.com/purcell/emacs.d/tree/master as a base :P

16:42 beutdeuce: after i get the right output, i am constantly getting a null pointer exception, why is that? => http://clojure.pastebin.com/m66074d66

16:43 Chousuke: beutdeuce: you have parens around (println "true")

16:43 that means you're calling the return value of (println "true")

16:43 which is nil

16:46 arohner_: is there a version of memoize out there that only memoizes the last N values?

16:48 Chousuke: hmm

16:48 Can't think of any, but it should be fairly easy to make one

16:48 arohner_: yeah, I just wanted to make sure I wasn't duplicating effort

16:48 Chousuke: fetching the memoised value would have to be O(n) though

16:49 arohner_: why?

16:50 even a naive version would probably be acceptable. I'm memoizing a fairly expensive function, and it doesn't need to store too many values ( < 1000)

16:50 Chousuke: well, you have to remove the old values at some point I guess. how are you going to know which values are old if you have just a map?

16:50 clojurebot: map is *LAZY*

16:50 Chouser: you'd definitely need more bookkeeping

16:50 arohner_: yeah

16:51 the memoized function is run as part of a webpage, and the values can change over time, so unbounded memory growth is not acceptable

16:54 Chouser: you'd probably want lru, so a lookup causes an entry to be immune from deletion for a while

16:54 Chousuke: you could always do periodic "garbage collection" on the memoised map.

16:55 Chouser: if you had a map of args -> lookup-seq-num, that could be updated in constant time for each cache hit

16:55 Chousuke: yeah. then go through it every once in a while and remove entries from the actual memorised map that are too old

16:55 Chouser: but then on insert you'd have to O(1) walk that map looking for low-numbered values

16:58 porpoise: I just started using the clojure-install setup from ELPA. What's the correct way of adding my code directory to the search path, and add my java classpaths and native libraries?

16:58 Previously I was directly editing slime's invocation of java

16:59 Chousuke: swank-clojure-extra-jar-paths or something?

16:59 it's in the customize group for swank-clojure

17:01 porpoise: thanks

17:02 lisppaste8: hiredman annotated #83651 "wall-hack-method" at http://paste.lisp.org/display/83651#1

17:02 technomancy: porpoise: it's actually generally easier if you extract all your dependencies in one place rather than adding jar files to your classpath one-by-one

17:04 beutdeuce: Chousuke: if i remove parens around println "True", it says if has too many args

17:10 technomancy: beutdeuce: remove just one pair of parens

17:11 beutdeuce: technomancy: still says too many args:

17:11 (defn elem

17:11 [x xs]

17:11 (if (= x (first xs) )

17:11 print "True"

17:11 (if (= (rest xs) nil) print "False" ((elem x (rest xs))))))

17:12 technomancy: beutdeuce: you removed two levels of parens around print "True"

17:13 also you didn't put it inside the if expression like I said

17:13 beutdeuce: could u please paste the right version, i'm a bit confused right now

17:13 technomancy: sure, but I think you might want to take a step back and try reading some more existing code before you proceed.

17:15 here's the working version: http://clojure.pastebin.com/m1cbcfc5f

17:17 beutdeuce: i appreciate your help

17:17 technomancy: np; I hope you get things figured out

17:17 beutdeuce: say, is ther infix notation on clojure, like in haskell `` ?

17:17 Chousuke: no

17:17 hiredman: ugh

17:17 beutdeuce: k

17:20 Chousuke: beutdeuce: lisp has this concept of "forms". a single form evaluates to a single value. a form is either "atomic", or a composite form. '5', '"foo"', 'bar', ':bar' etc. are atomic forms. '(print "2+2=" (+ 2 2))' (a list) '["foo" 5]' (a vector) etc. are composite forms. composite forms. list composite forms are evaluated specially in that the first item in the list composite form

17:20 is considered an "operator" and the rest are the arguments; so, the list form evaluates to whatever that operator called with the arguments returns.

17:20 beutdeuce: further, there are macros and special forms which can "bend" the rules a bit.

17:21 mariorz: what should I use to parse a huge xml file without loading the whole thing to memory?

17:22 Chouser: mariorz: you can try clojure.contrib.lazy-xml

17:22 mariorz: Chouser: cool

17:22 Chouser: but it's pretty easy to accidentally bring in the whole thing

17:23 I'd be interested to know how it works out for you.

17:23 mariorz: why accidentally?

17:23 Chousuke: beutdeuce: if is one example of a special form; but if you look at '(if (= 2 2) "yay" (print "nay"))', it is still the if operator, called with three arguments: the condition, the form that is evaluated and returned if the condition is true, and the form that is evaluated and returned when the condition is false.

17:24 Chouser: mariorz: if you have <doc><t1>...10GB of nested data...</t1><t2>foo</t2></doc>

17:24 mariorz: ...and you ask for doc's second child, the whole thing gets parsed

17:24 beutdeuce: Chousuke: k

17:25 mariorz: Chouser: makes sense, ill let you know how it owrks out

17:25 Chousuke: beutdeuce: in this case, the second argument gets evaluated and returned, yielding the value "yay"; if the condition were instead false, the third argument would get evaluated, having the *side-effect* of printing "nay", in addition to yielding the value nil

17:26 beutdeuce: ah

17:27 Chousuke: beutdeuce: as if only takes three arguments, each of the result branches can only contain one form.

17:28 beutdeuce: makes sense

17:28 Chousuke: beutdeuce: sometimes, if you need to evaluate more forms (for side-effects), you can wrap them in a do form, which evaluates all its arguments in sequence.

17:28 beutdeuce: i see, like Haskell

17:28 question, if i made a .clj file with my elem function defn'ed in it, is there a clojure function that loads it or imports it?

17:29 Chousuke: so (if true (do (print "1") (print "2")) (print "not true"))

17:29 beutdeuce: yeah

17:30 Chousuke: beutdeuce: usually, you want to declare a namespace at the top of your file

17:30 beutdeuce: but you can also use (load "foo") (no .clj) to just "include" a file

17:31 beutdeuce: Chousuke: cool thanks. i g2g for now. Thanks for all the help. and technomancy.

17:47 hiredman: I am always surprised when I see people who are obviously unfamiliar with clojure doing performance testing

17:48 it seems to imply performance is the first thing people look at

17:48 which is at odds with, well, me

17:48 Chouser: heh

17:51 mariorz: Chouser: so if I use parse-trim on the file the content wont be loaded to mem until I actually call it using :content, right?

17:52 Chouser: that's the idea

17:53 mariorz: cool

17:56 i dont think its working

17:56 just calling trim-space on the file makes me run out of heap space

17:56 er parse-trim

17:56 Chouser: :-(

17:57 what are you doing with the result of parse-trim?

17:58 mariorz: assigning it to a var

17:58 Chouser: bah. that ought to be safe.

17:58 mariorz: (def foo (parse-trim "bigfile))

17:59 fsodomka: Chouser: logging at http://clojure-log.n01se.net/ doesn't work recently for me

18:00 Chouser: mariorz: try (parse-seq "bigfile" startparse-sax 1)

18:02 mariorz: Chouser: cool, i think that works

18:03 Chouser: mariorz: ok. without that it was going ahead in the background trying to parse the whole thing.

18:03 So I essentially lied to you before. :-P sorry.

18:03 mariorz: hah np

18:04 Chouser: fsodomka: bleh. indeed. thanks.

18:05 fsodomka: can't fix it tonight. I'll try to get to it soon.

18:05 I've got the logs, but they're in the wrong format, so once its fixed the intervening days should show up

18:05 mariorz: Chouser: those this mean i could use parse-trim as well as long as i suply startparse-sax?

18:06 s/those/does/

18:06 fsodomka: Chouser: cool, looking forward to it

18:06 Chouser: no, it's the 1 that matters

18:06 fsodomka: Chouser: thanks!

18:06 Chouser: that tells the parsing thread how far ahead of the consumer it's allowed to get

18:07 mariorz: Chouser: ok, startparse-sax is the default aprser anyway?

18:07 Chouser: oh, yes -- (parse-trim "bigfile" startparse-sax 1)

18:07 yes, startparse-sax is the default

18:07 mariorz: cool, thanks for the help!

18:08 Chouser: the pull-parser is better, but requires another jar: http://www.extreme.indiana.edu/xgws/xsoap/xpp/

18:09 huh. that's kinda weird. Looks like if you put that xpp jar in your classpath, (parse-trim "bigfile") may just do what you want

18:10 mariorz: why?

18:11 it automatically sets a queue size?

18:12 ah i see

18:12 If no parser

18:12 is specified and org.xmlpull.v1.XmlPullParser is in the classpath,

18:12 this superior pull parser will be used."

18:15 westajay: is there a simpler api function for testing if all elements in a collection are true?

18:15 other than doing this

18:15 (every? (fn[x] x) [true true true])

18:16 Chousuke: westajay: there's the "identity" function

18:17 scgilardi: (every? true? a-collection) (if you mean literally true and not just non-nil and non-false)

18:18 westajay: scgilardi: that works

18:19 thank you sir

18:19 scgilardi: westajay: you're welcome :)

18:20 Raynes-: ,(true? (true? (true? true)))

18:20 clojurebot: true

18:20 Raynes-: True!

18:21 scgilardi: Chousuke: you asked earlier about the prohibition on periods in lib names. Rich requested that around the time he integrated the use and require stuff into Clojure. As I recall, the rationale was to keep things as simple as possible.

18:22 [ the prohibition I'm talking about is that this is not currently accepted: (:use (clojure.contrib sql sql.test)) ] because sql.test contains a period.

18:24 Before it was simplified, one could use the prefix list concept nested arbitrarily deeply: (:use (clojure (contrib sql (sql test))))

18:24 * hiredman dies

18:24 hiredman: clojurebot: CA?

18:24 clojurebot: CA is Contributor Agreement: http://clojure.org/contributing

18:29 Raynes-: I wish I had a printer, so I could print that. :(

18:30 I'd buy one, but hiredman took all my moneys.

18:31 hiredman: all the money you where going to get paid for NPEs

18:31 scgilardi: given his recent demise, at least that's one problem you won't have any more

18:31 hey!

18:42 Modius: Is clojure's "doall" a function or a macro?

18:43 hiredman: ,(meta #'doall)

18:43 clojurebot: {:ns #<Namespace clojure.core>, :name doall, :file "clojure/core.clj", :line 1780, :arglists ([coll] [n coll]), :doc "When lazy sequences are produced via functions that have side\n effects, any effects other than those needed to produce the first\n element in the seq do not occur until the seq is consumed. doall can\n be used to force any effects. Walks through the successive nexts of\n the seq, retains the head and retu

18:43 Modius: Does that mean it is a function?

18:43 hiredman: ,(meta #'defn)

18:43 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name defn, :file "clojure/core.clj", :line 189, :doc "Same as (def name (fn [params* ] exprs*)) or (def\n name (fn ([params* ] exprs*)+)) with any doc-string or attrs added\n to the var metadata", :arglists ([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?])}

18:43 hiredman: yes

18:44 if it is a macro there iwll be a :macro true

18:46 scgilardi: ,(doc doc)

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

18:46 scgilardi: clojurebot has a custom doc func?

18:47 hiredman: yes

18:47 well, custom doc macro

18:47 scgilardi: right. is it to minimize lines of output or to solve some security problem?

18:48 hiredman: well, the way doc prints out stuff is not irc friendly

18:48 the dashes, the spaces, etc

18:49 scgilardi: makes sense. clojure.core/doc also prints out "Macro" for macros.

18:49 hiredman: oh really

18:49 how useful

18:55 beutdeuce: if i have a fun.clj file with (ns "lib") at the top, can i use (in-ns "lib") from Repl to load it?

18:57 hiredman: no

18:57 Raynes-: You could just load the file.

18:57 hiredman: namespace names are symbols

18:57 beutdeuce: how?

18:57 hiredman: not strings

18:57 (ns lib)

18:57 (in-ns lib)

18:58 and in-ns does not load anything

18:58 it jsut switches to another namespace

18:58 beutdeuce: how would i be able to load an external clj file?

18:58 hiredman: you can just one of the load functions or require or use

18:58 Raynes: beutdeuce: (load "path")

18:58 hiredman: I win.

18:59 beutdeuce: doesnt work

18:59 tells my no source file

19:00 Raynes: beutdeuce: It has to be on your classpath, by the way.

19:00 I think.

19:00 beutdeuce: is there any alternative way?

19:00 Raynes: Require or use, but it still has to be on the classpath.

19:01 Once again, I think. I never have to do stuff like this. I use Slime.

19:01 beutdeuce: hmm. whats that?

19:02 works with clojure?

19:03 Raynes: It's what you specify when you start up the clojure REPL. java -cp <paths that you want on the classpath separated by :'s on *nix and ;'s on windows> -jar clojure.jar

19:03 -cp adds whatever directories you specify to the classpath.

19:03 For example: java -cp /home/rayne/clojure:/home/rayne/clojure2 -jar clojure.jar

19:04 Anything in Clojure and Clojure 2 will be on the classpath.

19:04 I don't know enough about the classpath to really /explain/ it, I just know how to use it.

19:04 If anyone else can explain it better, feel free to step in. :)

19:05 beutdeuce: thats clear enough

19:05 whats slime though?

19:05 Raynes: It's an Emacs mode for Lisp.

19:05 Most people use it and clojure-mode+clojure-swank for their clojure editing needs.

19:06 technomancy: beutdeuce: there's an explanation/tutorial at http://technomancy.us/126

19:06 Raynes: technomancy: Thank you. I was scared to death he was going to ask something more complex about Slime. :|

19:07 beutdeuce: :P

19:09 technomancy: hehe

19:10 lisppaste8: mariorz pasted "untitled" at http://paste.lisp.org/display/83661

19:10 mariorz: Chouser: still around?

19:10 beutdeuce: i'm on a mac and i have no idea what i set my inferior-lisp-system to, i dont even know where its located

19:11 technomancy: beutdeuce: if you read the article I linked to, you shouldn't have to configure that stuff by hand

19:12 beutdeuce: works with mac?

19:23 technomancy: beutdeuce: others have reported success

19:23 can't test myself

19:23 beutdeuce: technomancy: nothing happens when i do M-x package-list-packages

19:26 technomancy: beutdeuce: you've triggered an obscure elpa bug I've been unable to reproduce. =\

19:26 try restarting Emacs; if that doesn't help, rm -rf the elpa directory inside your .emacs.d and try again

19:26 beutdeuce: emacs-starter-kit in currently in ~/.emacs.d/emacs-starter-kit

19:26 it should work

19:27 * technomancy wonders why everyone else runs into that problem but him

19:27 Knekk: Sorry, I missed the top of the discussion. This is for setting Emacs for Clojure?

19:28 beutdeuce: Knekk: yeah, trying to get emacs-starter-kit to work

19:28 Knekk: beutdeuce: where can I download that?

19:28 beutdeuce: Knekk: http://technomancy.us/126

19:28 technomancy: beutdeuce: emacs-starter-kit should actually be just ~/.emacs.d rather than nested inside it

19:29 beutdeuce: oh

19:30 nice, seemed to work now

19:30 woa, this is amazign

19:36 technomancy: yay =)

19:45 beutdeuce: i'm getting trouble loading slime after emacs restarts

19:48 technomancy: beutdeuce: does it work after you open a .clj file?

19:48 beutdeuce: i think i know a fix, instead of adding a call to "(eval-after-load 'clojure-mode '(clojure-slime-config))" to .emacs, i load it to init.el

19:51 argh, didnt work

19:51 its as if it doesnt recall slime after i restart emacs

19:52 technomancy: init.el is the equivalent of .emacs

19:52 beutdeuce: i put it there, but then it gave me an error

19:53 when i take that line out, it works again, just not slime

19:53 technomancy: can you paste the error?

19:54 beutdeuce: it flashes quickly then emacs loads to default gnu screen

19:55 technomancy: right; if you switch to the *Messages* buffer you can see the error

19:56 beutdeuce: does it matter where i put: (eval-after-load 'clojure-mode '(clojure-slime-config)) ?

19:56 technomancy: if you're using the starter kit, put it in a file in .emacs.d named after your username + .el

19:56 that way you won't get merge conflicts if you update to a newer version of the starter kit

19:57 beutdeuce: well, no error, but M-x slime doesnt work

19:57 oh eait

19:57 wrong dir

19:57 h/o

19:58 yeah

19:58 still no slime

19:58 do i have to load username.el manually?

19:58 its in my .emacs.d/currently

19:59 technomancy: no, that happens for you

20:00 try M-x slime after you've opened a .clj file

20:00 beutdeuce: (eval-after-load 'clojure-mode '(clojure-slime-config)) is whats in there, should i try to run that in emacs itself?

20:00 technomancy: no, you don't need to load it manually

20:01 beutdeuce: technomancy: yeah, it only works when i load a .clj file, is there a way to get it work without loading a clj file?

20:02 technomancy: beutdeuce: try just putting in (clojure-slime-config) instead of (eval-after-load [...])

20:02 beutdeuce: makes sense, i'll try

20:02 technomancy: recent versions do this, but my packages haven't been uploaded to elpa yet. =\

20:04 beutdeuce: yep now works, thanks for all your help!

20:05 technomancy: no problem

20:12 spaceman_stu: Hi guys - I'm trying to write a build.xml file and am getting an error saying the SAXParserFactoryImpl can't be found on the line I call an xml function from contrib. I've got the contrib jar included - any tips to getting it working?

20:22 gstamp: spaceman_stu: maybe you need to include the xerces library?

20:25 spaceman_stu: gstamp: That may well be it, but I don't understand why I wouldn't have had to deal with that before - it runs fine from slime. I'm guessing somethign with the classpath isn't right

20:28 hiredman: man, almost everything is a reader macro

20:37 skalnik: Anyone know of a good resource for Ruby programmers looking to play with Clojure?

20:40 ataggart: ,(if (Boolean. "false") :weird :ok)

20:40 clojurebot: :weird

20:42 Anniepoo: skalnik, I'm learning from Stuart Halloway, Programming Clojure, it's pretty good

20:42 skalnik: I'll look into it, thanks.

20:42 Ah, pragprog. Must be good :)

20:42 Chousuke: ataggart: I think you're supposed to use Boolean/valueOf :)

20:43 ataggart: it's good, though it helps to know a bit of java

20:43 Anniepoo: it shares the usual pragmatic problem of being more boosterish than actually informative

20:43 ataggart: chousuke: I know, just testing it out as osmeone brought it up on reddit

20:43 Raynes: Anniepoo: It's pretty informative regardless.

20:43 Chousuke: Making your own Boolean instances is weird anyway :P

20:44 Anniepoo: yes, agree

20:44 Chousuke: I wonder why it's even supported

20:44 Raynes: It's more of a "pump you up and get you going tutorial!" than a endless pit of knowledge.

20:44 But Clojure is a Lisp. There just really isn't all that much to talk about. The proof is in the kodak.

20:45 mariorz: does map make use of seperate threads?

20:46 Chousuke: no

20:46 there's pmap for parallel mapping.

20:46 mariorz: im having a weird error where calling map returns a transaction not in thread error

20:47 Chouser: map is lazy

20:47 mariorz: mapping a function to a persitnat list

20:47 no, it is but im trying out with a normal list

20:47 Chouser: but what map returns is lazy regardless

20:48 if map is called inside a dosync, but what it returns gets passed to outside the dosync, you're likely to have problems

20:49 Anniepoo: sorry Raynes, I got distracted by RL, yes, I'd agree with you.

20:49 my complaint is only that at times I feel like, in common with all the PP series, it sacrifices

20:50 clarity in elucidating some boring but vital part of the language for an 'ooh wow, isn't that cool' demo

20:51 but that aside, it's a pretty clear intro to the language, esp. if you're not coming from another functional language

20:54 Raynes: I've never read a pragprog book.

20:54 I generally stick to O'Riley books.

20:54 Anniepoo: I've read many, they all have this same problem.

20:55 O'Riley used to be God, they seem to have let a lot of fluff in at some point

20:56 mariorz: Chouser: http://paste.lisp.org/display/83670

20:56 thats what i mean

20:56 Raynes: Real World Haskell is a good, comprehensive book. But it's amazing the amount of stuff they managed to screw up in it.

20:56 arohner_: Raynes: what did they screw up in RWH?

20:57 I have the book, but I"m not a haskell expert and I didn't read it carefully

20:57 Raynes: arohner_: Various stuff, they contradicted themselves in some chapters, plenty of typos, they introduce things at the wrong time, some of the examples apparently don't even work correctly, and the coding style changes depending on whoever is writing the current chapter.

20:58 But it still manages to be a very good read.

20:58 arohner_: I got it mainly to read about what was different in haskell rather than a serious attempt to learn it

20:59 Raynes: arohner_: You could have just read it online, if that was the case.

20:59 Chouser: mariorz: yeah, try wrapping your (map ...) in a (doall ...)

21:00 mariorz: Chouser: coolness, i get it now

21:00 i.e. what you meant with map returns lazy

21:01 Anniepoo: I've found one error in Halloway, and it's a trivial one

21:02 You know, I'm also having to deal with building a big C# library today, and the difference is truly breathtaking

21:02 hiredman: Chouser: do you know of a no-op reader macro off hand?

21:03 Chouser: #_

21:03 or what do you mean by no-op?

21:03 mariorz: right

21:03 hiredman: Chouser: dunno

21:03 //no op macros return the reader

21:04 Chouser: ,[1 2 3 #_ 4 5 6]

21:04 clojurebot: [1 2 3 5 6]

21:04 hiredman: from LispReader

21:05 Chouser: hm -- a reader macro can use thre reader obj as a sentinel, looks like.

21:06 hiredman: hiredman.reader=> (eval (my-read))

21:06 (+ 1 2)

21:06 3

21:06 clojurebot: 3

21:06 Chouser: ah, a comment

21:06 ; is a reader macro

21:06 hiredman: Chouser: I see

21:07 Chouser: CommentReader.invoke() walks to the end of the line, then returns the reader as a sentinel that no form has actually been produced yet

21:08 looks like #_ may be the only other one. It reads the following form and likewise indicates nothing has been read yet

21:08 ,(read-string "; foo")

21:08 clojurebot: java.lang.RuntimeException: java.lang.Exception: EOF while reading

21:08 Chouser: ,(read-string "; foo\n5")

21:08 clojurebot: 5

21:09 mariorz: :(

21:09 im still running out of heap space

21:10 Chouser: you can make your heap bigger when you launch java

21:10 mariorz: but it should not be loading the whole file to mem this way, right?

21:11 Chouser: you're walking all the way to the end of the xml file?

21:11 or do you stop early?

21:11 mariorz: all the way

21:11 http://paste.lisp.org/display/83670#1

21:11 Chouser: hm... that may be the problem...

21:12 mariorz: how so?

21:12 Chouser: as in, the whole file is not loaded at the beginning, but it's probably all cached

21:12 so if you don't bail early, it may all end up in memory after all...

21:13 mariorz: what do you mean bail early?

21:13 like jsut parse the first x elements ?

21:14 Chouser: Right. The normal clojure.xml/parse parses the whole file before it even returns.

21:15 but lazy-xml will parse only as much as you demand -- however if you demand all of it, it may all end up in memory after all

21:15 hang on, gotta put a kid to bed. back in a few.

21:15 mariorz: k

21:20 shouldnt the cache have a max size so this doesnt happen though?

21:25 Raynes: How cute. Chouser has minicoders.

21:30 mariorz: memory usage for the java process never seems to go up though

21:30 just cpu

21:30 arohner_: right, java has a limit on how much ram it will take

21:30 Chouser: mariorz: it's the regular lazy seq caching -- each cell caches it's own value, there's no global view.

21:31 mariorz: but that low?

21:31 around 90mb

21:31 Chouser: the solution is to make sure that you release earlier head(s) of the seq(s) as you walk through.

21:32 mariorz: the seq returned by the map right?

21:32 Chouser: how do i do that?

21:32 Chouser: but if you're walking through (:content node), the node map is hanging onto the head so it must all end up in memory

21:32 Raynes: Chouser: How many minicoders do you have?

21:32 Chouser: none coding yet. :-)

21:33 Raynes: :)

21:34 mariorz: so the seq to which i apply the doall is lazy, but as the doall evaluates each cell in the seq its value gets cached which is what eats up the heap, is that whats happening?

21:34 Chouser: yes

21:35 and if it's not allowed to do any processing after you leave the with-tx block, then you have a bit of a problem.

21:35 oh!

21:35 are you throwing away the return value of the map?

21:35 mariorz: so what would be a way around that? :)

21:35 Chouser: save_node is about side-effects?

21:36 mariorz: well it stores the node value in a db

21:36 Chouser: right -- you don't care about the return value of save_node, right?

21:36 mariorz: nope

21:37 Chouser: ok, then you should use (dorun (map ...)) or better yet (doseq ...) inside your with-tx

21:37 well, I should warn you that I'm not sure it's possible to get what you want without restructuring lazy-xml itself

21:38 but it might be. And even if lazy-xml is doing the right thing, using (doall (map ...)) would thwart it.

21:39 mariorz: from the api docs it would seem doseq is what i want no?

21:39 Chouser: yes

21:41 mariorz: same error

21:41 Chouser: yes.

21:42 mariorz: but why?

21:43 Chouser: now, the next thing is that bigfile is a map which contains (nested in a ways) the head of the seq you're walking through

21:44 after your doseq is done (if it didn't run out of heap), you can still go get the first item in seq. The fact that you can means it's been stored in exactly the way that you can't allow

21:46 mariorz: didnt really understand that

21:47 Chouser: ok, let's look at a simpler example

21:47 (let [x (map #(str "A number: " %) (range 1e7))] (last x))

21:47 x is a very long lazy seq of strings.

21:47 I say "is" but more accurate would of course be to say "promises to be"

21:48 mariorz: right

21:48 becuae its lazy

21:48 Chouser: Right. Now, (last x) has to walk to the end of the seq and return the final item.

21:48 as shown above, this will happen fairly quickly and return the result.

21:48 ,(let [x (map #(str "A number: " %) (range 1e7))] (last x))

21:48 clojurebot: Execution Timed Out

21:48 Chouser: hm, not so quickly.

21:51 well, anyway, it should work in your repl, returning a string after a few seconds

21:51 mariorz: right

21:51 Chouser: it doesn't consume memory because nothing is able to get to the first element of x, so the JVM reclaims the memory used to cache those values

21:51 gko: Hello... How to check if an element is in a list?

21:52 Chouser: gko: perhaps a set would work better?

21:52 mariorz: but one small change breaks it:

21:53 gko: Oh: ((set my-list) 1)

21:53 hiredman: grrr

21:53 Chouser: gko: sure, but that walks through the whole list to build that set before looking it up. Can you not use a set through your code instead of that list?

21:54 (let [x (map #(str "A number: " %) (range 1e7))] [(first x) (last x)])

21:55 gko: Chouser: it was just a general question... I have already been using sets because of this...

21:55 Chouser: mariorz: in this case, the head of the seq is retained (so that the literal [] vector can do what it needs to), so the JVM does not release memory, and it tries to hold the entire seq in memory

21:56 gko: ah.

21:56 ,(.contains '(a b c) 'b)

21:56 clojurebot: true

21:57 gko: (set 1 2 3)

21:57 mariorz: Chouser: ok, and this happens within lazy-xml becuase it maintains a pointer to the head of the document?

21:57 Chouser: mariorz: right. bigfile points to the whole document

21:58 ataggart: ~some

21:58 clojurebot: Hello, gnuvince

21:58 ataggart: (doc some)

21:58 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

21:58 Chouser: mariorz: I'm looking at lazy-xml's code to see if i can spot any head-retaining there, but I'm not sure...

21:58 mariorz: so anyway, the next thing that is necessary (but perhaps not yet sufficient) is to not store bigfile globally.

21:59 ataggart: gko: use some

21:59 gko: ataggart: ?

21:59 ataggart: (doc some)

21:59 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

21:59 mariorz: Chouser: just something like (with-tx (doall (map save_node (:content (parse-trim "file.xml" startparse-sax 1)))))

22:00 ?

22:00 Chouser: using xpp would not help with this right?

22:01 Chouser: mariorz: try (with-tx (let [bigfile ...] (doseq [node (:content bigfile)] (save_node node)) ...

22:01 mariorz: or what you had (but with dorun instead of doall)

22:02 mariorz: this step is necessary anyway. it's possible yet that lazy-xml itself is hanging onto something, in which case the xpp code path may be better (or worse) ... not sure yet.

22:02 mariorz: doseq or dorun?

22:02 Chouser: I prefer doseq. It's your choice.

22:02 both return nil which is the critical thing

22:02 mariorz: k

22:03 thx again for the help, going for a bite and will mess aorund some more later

22:03 gko: ataggart: Oh OK... any reason why lists are not functions like maps or sets?

22:04 ataggart: in what sense?

22:04 Chouser: mariorz: ok

22:04 gko: (my-map key) => value

22:04 ataggart: gko: ah because sets and maps have O(1) access on their keys

22:04 so they can act as functions

22:05 contains? only works on keys, which lists dont have

22:05 gko: ataggart: right...

22:05 ataggart: (contains? [:a :b :c] 2)

22:05 ,(contains? [:a :b :c] 2)

22:05 clojurebot: true

22:06 ataggart: if you want to spin through a list, you can do it with some

22:06 Chouser: ,(some #{'c} '(a b c))

22:06 clojurebot: c

22:07 gko: why , in front of your samples?

22:07 ataggart: it tells clojurebot to execute it

22:07 though it sometimes excutes code anyway

22:08 it's feisty

22:08 gko: ,1

22:08 clojurebot: 1

22:08 gko: :)

22:08 couldn't clojurebot puts the evaluated expression?

22:09 that's nice

22:11 ataggart: ~botsnack

22:11 clojurebot: thanks; that was delicious. (nom nom nom)

22:25 hiredman: do clojure's tests include reader tests?

22:30 arohner_: hiredman: some

22:30 there's a clojure.test-clojure.reader ns

22:31 it's hardly comprehensive

22:31 hiredman: well

22:32 my wrapper around LispReader passes that, so it's time to start replacing bits and pieces

22:32 arohner_: what are you working on?

22:33 hiredman: replacing Lispreader.java with clojure code

22:34 arohner_: cool

22:34 hiredman: http://github.com/hiredman/reader/blob/afb9e6266358fc965c9572a1cafc57dc15908e42/hiredman/reader.clj

22:50 arohner_: sigh. Why does java provide SimpleDateFormat, and then not provide constants for really common date formats, like RFC 822 and ISO8601?

23:23 durka421: why doesn't clojure support java variadic methods (like PrintWriter/printf) without to-array?

23:35 arohner_: durka42: java variadic methods are sugar for "normal" functions that take arrays

23:35 durka42: i suppose there's no way for clojure to detect them without reflection

23:35 or maybe even with the use of reflection

23:36 i know they take arrays, hence my (slight) annoyance at having to play with to-array

23:45 * durka42 feels stupid

23:45 durka42: i had caps lock and couldn't figure out what the _hell_ vim was doing

23:45 slaney: heh

23:45 I have done that

23:46 more than once

23:46 adl

23:46 sadly

Logging service provided by n01se.net