#clojure logs

2009-07-15

00:02grrrthow can you test if a name is a function? I guess isa? or instance? wouldn't work here?
00:04gnuvincegrrrt: fn? and ifn? come to mind
00:04gnuvince,(fn? map)
00:04clojurebottrue
00:04grrrtahh doh!
00:04grrrtsigh, brain has left the office for the day :)
00:04gnuvince,[(fn? {}) (ifn? {})]
00:04clojurebot[false true]
00:04grrrtcheers
00:05gnuvincenp
00:13arohnerdoes anyone have experience running a profiler on clojure code in OSX?
00:13arohneror linux. but eclipse's TPTP is not working for me
02:29JomyootIs there example of how to structure clojure into different source files?
02:29Jomyootname spaces and etc?
02:29Jomyootbasically a simple project structure
02:29Jomyooti so far have used clojure as glue code. so all in one file
03:25ataggartvery loosely speaking, one clj file for a namespace
04:54Jomyootshould they use or require each other?
05:05AWizzArddepends on how you want to use them
05:06AWizzArdboth are valid options
05:06AWizzArdI use 60% and require 40%
05:39Jomyootis there a guilde or tutorial for this?
05:50ataggartwith require you still need to use a namespace (or namespace aliias). with use you don't need to prefix everythign with a namespace
05:50ataggartit's style prefernce more than anything
06:03Jomyoot_do i put deeper name spaces into deeper folders?
06:04Jomyoot_or throw all files into same folder
06:04Jomyoot_does java style folder/package mapping still work here?
06:06jdzthe Java style hierarchical file/namespace relation remains
06:06jdzhttp://clojure.org/libs
06:08Jomyoot_any idea when cascade will be available?
06:09jdzwhat's cascade?
06:11Jomyoot_something tapestry guy said he would make
06:11Jomyoot_for clojure
06:11Jomyoot_that's all i know
06:11ChousukeJomyoot_: you can also split a namespace into multiple files by having the "main" file use 'load to "include" other files
06:11Jomyoot_i don't even know if tapestry is popular
06:13Jomyoot_:use com.test.me.ns would that go look for the com/test/me/ns.clj file? assuming that it's all source file
06:13Chousukeyeah.
06:14Chousukesee (doc ns) and (doc require) at least.
06:14Chousukethe ns documentation is a bit scattered
07:36Neunhello, why does this not work: (eval (list #(%) "foo"))
07:36Neunwhy do I have to quote the function?
07:38cemerickNeun: is foo the function you're trying to invoke?
07:39NeunI tried this (map (comp eval list) list-of-functions list-of-elemts)
07:40Neunthis works though: (map #(%1 %2) list-of-functions list-of-elements)
07:40cemerickeval is unnecessary unless you've got symbols, etc., as opposed to actual functions
07:41cemericke.g.:
07:41cemerick,(eval '(+ 5 6))
07:41clojurebotDENIED
07:41cemerickbah
07:41NeunI see
07:41cemerickanyway, that would return 11, but clearly, you just want to invoke a fn directly:
07:42cemerick,(+ 5 6)
07:42clojurebot11
07:42jdzNeun: would just plain (map apply list-of-functions list-of-elements) not work?
07:42Neunjdz: no, apply needs a vector of arguments
07:43jdzno, just a sequence
07:43cemerickNeun: not so:
07:43jdzwell, not really
07:43cemerick,(apply + (list 5 6))
07:43clojurebot11
07:43jdzthe last argument should be a sequnce
07:43cemerickright
07:43cemerick,(apply + 14 (list 5 6))
07:43clojurebot25
07:44jdz,(apply + 42)
07:44clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
07:47Jomyootcan (def x (ref (hash-map)) bedefined using (let) as well?
07:47jdzlet creates bindings in it's scope. when the scope is gone, so are the bindings.
07:49cemerickJomyoot: 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)})))
07:59rottcoddis there a way to call private functions in another namespace?
07:59cemerickrottcodd: (#'some.other.ns/fn-name ...)
08:00cemerick#'foo returns the var named by foo
08:00Chousukeand var just happens to delegate to its value if it appears in operator position :P
08:01cemerickI think that was a stroke of genius. Much nicer than other lisps where you really had to be conscious of that sort of thing.
08:03rottcoddcemerick: thanks
08:10rhickeydid anyone ever do a reasonable with-captured-bindings macro?
08:13cemerickach, I always get tripped up by the order of fns to comp
08:14rhickey(foo (bar (baz ... -> (comp foo bar baz)
08:14rhickeyi.e. comp just removes some parens
08:15cemerickrhickey: yeah, I just happen to use -> more often, which applies in the reverse order
08:15cemerickcomp is more consistent with mathematical notation, too, so this is really just a mental problem on my part
08:15rhickeyI have to think twice sometimes too :)
08:17rhickeyI 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
08:18rhickeysaw an F# presentation where they did everything with the :> operator, made people very comfortable
08:18cemerickheh. I have no idea what :> would mean.
08:18rhickeysorry, |> operator
08:18cemerickyeah, that doesn't ring any bells, either :-)
08:19Chouser$ means end-of-the-thing in regex and sh
08:19rhickeyright, I'm not advocating |>, but it had the same concept as pipe, put arg at end, except you have to keep repeating it
08:19cemerickah
08:20rhickeywe haven't used $ or | yet, probably not worth it for this
08:20rhickey-<, <-
08:20Chouser($-> coll (map foo) (filter bar))
08:20cemerickwell, I generally try to avoid shell scripting, so #(-> % .. .. ..) and comp are good enough for me :-)
08:21rhickeycemerick: really, you use -> and wouldn't use (pipe xs (map f) (filter p) (reduce op)) ?
08:22ChouserOne of the first clojure macros I ever wrote was called >>_
08:22Chouser(>>_ coll (map foo _) (filter bar _))
08:22rhickeyfor pipe?
08:23rhickeyfunny I would have gone the other way <<
08:23rhickeymaybe not
08:23Chouserit's going the same way as ->
08:23rhickeywell, it's generally useful, and should be standard
08:24Chouseryeah, I used >>_ once or twice early on, but being non-standard makes it tiring to communitcate with others
08:24rhickeyChouser: yes, in some sense (calls) but not others (args)
08:24rhickeyChouser: especially with a name like >>_ :)
08:24cemerickrhickey: 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.
08:24Chouserhmph
08:25cemerickStuff like that changes fast, though.
08:25Neunjdz: maybe I could write (map apply seq-of-functions (map list (seq-of-values)))
08:25wlrwhat's wrong with calling it just, er, pipe?
08:26cemerickFWIW, I use -> most often for simple navigation of data structures (-> foo :key deref seq last), etc.
08:26rhickeywlr: nothing, except for the other meaning of pipe (data structure, IO channel)
08:26rhickeycemerick: that's its intended use for sure
08:26jdzNeun: that should work.
08:27rhickeywlr: one reason -> isn't called 'thread'
08:27cemerickhonestly, I'd be very worried if I were regularly mapping and filtering my way through things. Linear time bounds aren't nearly good enough. :-)
08:27jdzNeun: despite the fact that i don't like how it looks :/
08:28Neunjdz: yes, there should be something better/cleaner
08:28rhickeyall of the seq fns are set up for pipe
08:28wlrrhickey: okay, competing concepts. thanks.
08:29rhickeyanyway, we've got -<, <-, >>_, $-> - any others?
08:29rhickey->>
08:30jdz=>
08:30Chouser--> <--
08:30jdz==>
08:30cemerick<- is the most intuitive of them all, at least with respect to ->
08:30jdz^.^
08:30jdzbut that's taken by meta
08:30jdz\m/
08:31jdz>.>
08:31rhickeyI think Clojure datalog lib is using <- ?
08:32cemerickshouldn'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?
08:33Chouserbut it's not proceeding right to left
08:33Chouserthat's why the left-pointing things may not be appropriate
08:33cemerickah-ha -- that's what I get for reading a random group posting on "pipe"
08:33Chouser(map f2 (filter f coll))
08:34rhickeyit's kind of imperative, take xs, map it, filter it, reduce it ...
08:35rhickeyIn the F# demo it made people comfortable to see code that looked like "do this, do that", but was actually functional
08:36rhickeyI'm now with Chouser that call order dominates the sense of order, not arg order
08:36rhickeyso ->> or --> working best right now
08:37Chousertwo > certainly stands out more than two -
08:37Chouser-=>
08:37rhickeyyup
08:37Chouser->*
08:37rhickey= and > makes one think numbers
08:37Chouser>-
08:38Chouser>>-
08:38rhickeyChouser: documenting the path to >>_, eh :)
08:38Chouser:-)
08:38cemerickmultiple >'s make me think of bit-shifts
08:39Chouser>--
08:39rhickeycemerick: me too, but ->> still seems like an arrow to me
08:39Chouser(>-- coll (filter x) (map y))
08:39rhickeywhich is kind of nice in being able to call them the two arrow ops
08:40rhickeyarrow threads and double arrow pipes
08:40rhickeythrough a series of calls
08:42cemerickof course, there's the inevitable clojure impl of haskell arrows :-P
09:01weissjis there a particular reason why there's no builtin function called != ? that just does (not (= a b))
09:02Chousukethere's not=
09:02cemerick,(doc not=)
09:02clojurebot"([x] [x y] [x y & more]); Same as (not (= obj1 obj2))"
09:02weissjah
09:02cemerickhrm, odd irc latency
09:02weissjwould never have thought to look for that. :)
09:03Chousuke! carries the "side-effect!" meaning
09:03weissjChousuke: even when the ! is at the beginning?
09:03cemerickI would have exempted it for !=, but oh well
09:04cemerickthat's one of the advantages of having a BDFL (or similar), as opposed to cargo-cult design.
09:06Jomyootdo I have to both (require) and (refer) a namespace in another file?
09:06jdzor just use?
09:06weissjcemerick: what are bfdl and cargo-cult designs
09:07cemerickJomyoot: 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
09:08Chousukerequire needs its argument quoted though :)
09:08Chousukeor you can use the ns macro
09:09JomyootSo (refer) without (require) does not work?
09:09ChousukeI've never used refer directly :/
09:10jdzrefer with require is called 'use', as far as i understand
09:10cemerickweissj: http://en.wikipedia.org/wiki/BDFL -- by cargo-cult, I meant a bikeshed-susceptible design process (http://bikeshed.com/)
09:10jdzand refer does work without require. see the documentation what refer does...
09:11JomyootI get java.lang.ClassNotFoundException: com.atcloud.build-tags-hash-map
09:12JomyootI have (ns com.atcloud
09:12Jomyoot (:use [clojure.contrib.sql]))
09:12Jomyootand (defn build-tags-hash-map [db] in the other file
09:12jdzdo you have a file com/atcloud/build_tags_hash_map.clj in your classpath?
09:13Jomyooti am idiot
09:13Jomyooti am supposed to use /
09:13Jomyootrather than . i think
09:15weissjis 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?
09:15weissjit'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)
09:16cemerickweissj: I think rhickey has said that it's possible that forward declarations could eventually be handled automatically
09:16weissjcemerick: cool
09:16cemerickuntil then, you can use declare to create those (undefined) vars, and then define them later in the file
09:17weissjcemerick: functions too?
09:17cemerickespecially functions
09:17cemerickIME, anyway
09:17weissjhm, i'm not sure if that makes things better or worse :)
09:17cemerickwell, it lets you structure your code how you want, anyway
09:18weissjcemerick: yeah, but you still have declarations at the top
09:18cemerickit generally doesn't happen that much, at least to me
09:18cemerick*shrug*
09:18weissjoh i see you can declare them all at once? nice
09:18weissjie (declare a b c d)
09:19rhickeycemerick: 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
09:19rottcoddshould I use *var* or var for variable names?
09:19jdzrottcodd: "variables" is a very stretched term
09:20rhickeyrottcodd: *var* only if you intend to dynamically rebind them
09:20cemerickrhickey: 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.
09:20cemerickregardless, it's surely a lot of work for a very small gain, IMO
09:20rhickeycemerick: it is certainly possible, but a lot of work for a very minor feature IMO
09:20rhickeyheh
09:20ChouserI 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.
09:22weissjChouser: 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
09:22rhickeywhat old time Lispers really want is not whole-file resolution, but simply the ability to compile with unresolved names and get runtime errors
09:22cemerickold-time *common* lispers, of course. The current situation in clojure is exactly like the schemes I remember.
09:23rhickeycemerick: yes, CL
09:24rhickeythere's the whole 'define your program in the debugger' thing
09:24cemerickrhickey: did you notice the type hinting that C. Nutter is adding to JRuby?
09:24rhickeycemerick: link?
09:26cemerickrhickey: http://twitter.com/headius/status/2639903017 http://twitter.com/headius/status/2640249841 http://twitter.com/headius/status/2640406401
09:28rhickeycemerick: java with 'end' ?
09:28cemerickouch :-)
09:29rhickeyI've said the same thing as far as Clojure becoming Java with parens
09:29rhickeywhat's the point?
09:29cemerickeither are surely better than Java -- if the hints are just there to keep the reflector away, then all's well
09:31cemerickrhickey: 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.
09:31rhickeycemerick: 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
09:34cemerickrhickey: Oh, I agree wholeheartedly, but then, I'm not involved in building or using a language for the masses.
09:34rhickeyHave you ever seen LinJ?
09:34rhickeyseems to have disappeared, but it was a lisp that generated idiomatic Java
09:35rhickeywas weighed down, IMO, by the need to support all Javaisms
09:36cemerickits 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
09:36weissjif 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?
09:36rhickeyafter 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?
09:36cemericktype-hinting is pretty painful as it is, but it's certainly necessary
09:37Chousukeweissj: wrap the java method call in a function
09:37cemerick(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)
09:37Chouserweissj: (let [foo (try (foo-fn) (catch Exception e "error-val"))] ...)
09:38weissjChouser: i see thanks
09:38Chouserthat is, the final value of the catch block is what 'try' returns on the exception case
09:39weissjChouser: yeah in my case i'm later checking for nil, so i'll have the exception clause return nil. that'll do it!
09:41Jomyootis lisp code supposed to be more managable?
09:41Jomyootthan JAVA?
09:42Jomyootonce you have lots of it?
09:42rhickeyso, last call, I'm thinking about calling 'pipe' ->>
09:43ChousukeJomyoot: that probably depends on how good you're at writing manageable lisp code :)
09:44ChousukeJomyoot: But lisp has more powerful tools for abstraction than java IMO, so I'd say yes.
09:45cemerickIf 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.
09:46cemerickI'm a little of both, but I've aspirations. :-)
09:51weissjis there a builtin function to execute a command on the command line (perhaps via java's Runtime/Process/execute api)
09:53Jomyootso using .java stuff does break immutablity
09:53weissjclojure.contrib.shell-out/sh - found it. doc search on execute found nothing, but 'exec' found this
09:53Jomyooti can modify their state without dosync
09:54yasonHmmm, was there a byte stream as a lazy sequence akin to line-seq ?
09:54cemerickJomyoot: you can break immutability in a variety of ways if you're really motivated and your data structures allow it.
09:55Jomyootwhat's the point of dosync when it's so easy to break immutability when using java objects
09:56Chousukethe point is that when you do use the immutable data structures, it allows for easy concurrency
09:56ChousukeClojure does not force immutability on you. It just gets harder and harder to keep your program working the more mutability you introduce
09:57cemerickit's pretty difficult to introduce mutability to begin with, if you stay within clojure.
09:57Chousukemutability support is pretty much an interop thing.
09:57Jomyootit is hard to write Clojure without using java interop though
09:58cemerickJomyoot: 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?"
09:58yasonJomyoot: depends. I don't know Java much so I tend to steer away from any Java interop automatically
09:58ChousukeHmm, perhaps.
09:58Jomyooti get your point
09:58cemerickJomyoot: Depends on your domain. I touch java very rarely.
09:58yasonJomyoot: I just wrap the most essential java stuff to get my stuff running (file i/o or GUI stuff) and stay with Clojure then
09:59Chousukeproper use of java interop is to keep it isolate from pure, functional clojure logic :)
09:59Chousukeisolated*
09:59yasonChousuke: that's what I was trying to say, with too many copies of "stuff" :D
10:00Chousukeof course, some java stuff is "immutable" as well, like strings, and thus not a problem.
10:01ChousukeIt seems that arrays are the worst troublemakers :/
10:35JomyootIs emacs still pretty as IDE for Clojure?
10:38weissjanybody 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:39weissjant actually takes a string for :level, but here it seems to insist on an internal class called "EchoLevel"
10:39shooverJomyoot: I'm not sure anyone has ever accused emacs of being pretty, for clojure or otherwise
10:39shooveruseful, sure
10:42JomyootWhat is equivalence of simple hash in Ruby like this { :a => 1, :b => 2, :c => 3} is that HashMap in Clojure then?
10:43ChouserJomyoot: {:a 1, :b 2, :c 3} is a map in Clojure
10:44scgilardiJomyoot: and literal maps are hashmaps
10:45Jomyootis 'a equivalence of :a in ruby?
10:46arbschtit's probably not wise to think in terms of direct equivalents
10:46liebkejomyoot, :a in ruby is equivalent to :a in Clojure
11:00weissjonce i delete a function definition in a file, and load it into the repl, how do i remove the binding from the repl?
11:01weissjdo i have to restart the repl?
11:01weissj(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:01Chousukeyou can either redefine the var to nil or something or use ns-unmap
11:02Chousukeit's pretty simple to write a function that "cleans out" a namespace
11:04weissjok, i think i got that
11:05weissjwhat's wrong with (ns myns (use lancet (:as 'ant)))
11:05weissjjava.lang.IllegalArgumentException: No value supplied for key: true (jonSuite.clj:1)
11:06Chouser(ns myns (:use [lancet :as ant]))
11:06Chouserexcept lancet probably needs to be longer
11:07weissjlonger?
11:07Chousershould be the fully-qualified namespace name
11:07ChouserHalloway didn't call it just "lancet", did he?
11:07scgilardiand :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:07Chousergood point!
11:08Chouser(ns myns (:use [lancet :as ant :only []]))
11:08weissjwait, i just want to refer to functions in lancet with the name ant instead
11:08weissjnot also bring in everything into my own ns
11:08Chouserright.
11:08Chouserso :only []
11:08weissjok
11:09scgilardichouser's most recent example is how I would write that
11:09Chouseror you could use 'require' instead, but these days I don't usually recommend that
11:09ChouserI'm still hoping to see those two merged at some point
11:09scgilardime too
11:11cemerickChouser: you don't like require + :as?
11:12Chousercemerick: it's fine until you decide there's one var you want to refer in
11:12Chouserso you had (:require [fully.foo :as foo])
11:12Chouserand now you have to change it to (:use [fully.foo :as foo :only [bar]])
11:13weissjChouser: halloway did just call it 'lancet', btw
11:13cemerickso you prefer :use + :as + :only?
11:14scgilardidid we come up with any downsides to (:use fully.foo :as foo) implying :only [] unless explicitly overridden?
11:14Chousercemerick: 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:15cemerickyeah, that's a point
11:15Chouserscgilardi: breaking change is a downside
11:15ChousukeChouser: couldn't you add a :refer after the require?
11:15cemerickscgilardi: 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:16ChouserChousuke: is :refer supported by something?
11:16scgilardicemerick: the escape hatch is :exclude []
11:16cemerickok :-)
11:16Chousuke(ns something (:require [foo.bar :as foo]) (:refer foo.bar :only [some stuff here]))
11:16ChousukeChouser: the ns macro?
11:16ChouserChousuke: ah. I guess that might work, though 'ns' doesn't document it.
11:17ChouserI'd rather have the namespace listed once anyway.
11:17ChouserChousuke: is there something wrong with :use + :only ?
11:17ChousukeChouser: not really.
11:17ChousukeI guess it's a matter of preference
11:18scgilardichouser: 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:18ChousukeI guess the combined effect of :as and :only is a bit confusing, too
11:18Chouserscgilardi: yes!
11:19Chousukeyou wouldn't expect the entire namespace to be available through the :as alias either.
11:19Chouserscgilardi: I find it ugly, but less painful than mixing both :use and :require in random ways in the same ns form
11:19ChousukeI wonder if ns actually does support :refer
11:19ChouserChousuke: good point. maybe :only is misnamed for :use.
11:19Chousuke(doc refer) ; refers to it though :P
11:19clojurebot"([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:20Chousukedamn, too lon
11:20Chousukeg
11:20ChouserChousuke: ns macro currently just maps the keywords (like :use and :require) to core function names, and calls them.
11:20scgilardichouser: 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:20Chousukeoh wait.
11:20Chousukerefer actually refers to :use, not :refer
11:21Chousukehmm...
11:25Chouserso the least-breaking way forward would be to introduce a new word and give it the semantics we now know we want
11:25Chouserand deprecate :use and :require
11:25scgilardichouser: 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:26Chouserbut using up another word has drawbacks too
11:26ChousukeChouser: :assimilate? :)
11:26Chouserscgilardi: hm... maybe.
11:26Chouser:demand
11:26Chouser:-P
11:26scgilardi:depend
11:26Chouseractually -- hm. :require doesn't do anything bad, it's just missing features. Maybe that's the way forward.
11:27scgilardiwhat's it missing?
11:27Chouserperhaps we could add :refer and support for default aliases to :require
11:27Chouserthen deprecate :use
11:33scgilardias a detail of the current implementation (:require [clojure.contrib.sql :use true]) is exactly equivalent to (:use clojure.contrib.sql).
11:34cemerickoh, poor Stuart :-)
11:34Chouseroh, does :only work with :require?
11:35scgilardionly when accompanied by ":use true" (but that could be changed pretty easily, I think)
11:36Chouseroh, I see.
11:36scgilardisounds pretty nice... add support for the refer options to :require and have them imply :use true (effectively)
11:37Chouserprobably still need something that means :exclude, or at least :exclude []
11:38Chouserso as to enable our lazy brethren
11:38Chouser:refer-all-because-i-care-more-about-myself-than-my-readers
11:39cemerickChouser: there *are* good reasons, aside from sloth
11:39Chousercemerick: really?
11:39Chouserin cases where :as z or something wouldn't suffice?
11:40cemerickwell, a throwaway :as name is just noise.
11:40cemerickI use use in conjunction with two namespaces that provide a pile of utility fns that we use throughout our codebase.
11:42cemericke.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:44Chouserhm
11:44Chouserok, would you buy :refer :all ?
11:45cemerickwhat, (:require [foo.bar :refer :all])?
11:45Chouseryeah
11:45cemerickfine by me
11:46cemerickIt's definitely a corner case, so I'm happy to accept a syntactic compromise in order to make everything else simpler.
11:50scgilardi: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:51scgilardithe full list is :exclude, :only, and :rename
11:52Chouserbut if :only is renamed to :refer (which I like very much) that raises the question of what :exclude and :rename should be called
11:52Chouser:refer-all-but for :exclude?
11:53scgilardiI 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:55Chouser 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:56duck1123I always mess up :exclude as :except
11:58scgilardiI 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:59Chouseron the other hand I care so much less about the name than the functionality. :-)
12:02scgilardiwith 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:08weissjif i want to create a java object, call a setter on that object, then return the object, do i need a var?
12:10Chousernope
12:10Chousernot even a local, if you use 'doto'
12:10Chouser(doto (new JavaClass) (.setFoo 5))
12:13rhickeyChouser, 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:13rhickeyI can never remember how to use use and require
12:13Chousukeheh.
12:19scgilardiI'm open to suggestions. Other than collapsing both use and require into one thing, I don't see obvious opportunities for vast simplification.
12:20rhickeyscgilardi: doing less is an opportunity
12:20rhickeythe use of the nested vector is tricky too
12:22scgilardiplease explain re: doing less
12:24rhickeywell, 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:25rhickeye.g. foo.bar.baz vs (foo.bar baz) seems like a feature but adds complexity
12:26scgilardiremoving the opportunity to use prefix lists to extract out common prefixes would lead to simpler, but more redundant ns forms.
12:27rhickeyscgilardi: I thought we'd go the other way
12:28rhickeyhaving just :uses vs :require and :use is good in and of itself
12:28rhickeythe nested structure is also tricky
12:29rhickeyI can't design it right now, just encouraging a search for simplification
12:29scgilardithat 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:29scgilardiok, I'll give it some thought
12:30Chouserif 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:30Chousereh
12:30Chousernm, I don't like that
12:31scgilardiAlong 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:31rhickeyscgilardi: sounds appealing
12:32scgilardirhickey: I'll write up what I have and post it to the developer's list.
12:32rhickeyscgilardi: thanks!
12:33scgilardichouser: 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:34rhickeycommas are free too
12:34rhickey(:uses (foo bar :as fr, baz :as fz)
12:35rhickeyignored but useful still
12:37rhickey(:uses (foo bar {:as fr} baz {:as fz :refer bleh}))
12:39rhickeynice because adding options doesn't require restructuring
12:39ChousukeI don't see the point of "foo bar" instead of foo.bar
12:39Chousukeor is it importing two libraries? :/
12:39rhickeyright 2
12:40rhickeyshare prefix
12:40cemerickwhere's the prefix, then?
12:40scgilardiFor 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:40rhickeycemerick: foo.bar and foo.baz
12:40cemerickah.
12:41rhickeyscgilardi: but a lot harder to parse, even with commas
12:41rhickeybetter with newlines
12:41scgilardibut compare: (:uses (foo [bar :as fr] [baz :as fz :refer bleh]))
12:42rhickeyscgilardi: I really dislike that because the two names are at different nesting levels when no options
12:42rhickey(:uses (foo bar [baz :as fz :refer bleh]))
12:43rhickeyick^
12:43scgilardiok, I understand that
12:44rhickeysaving typing is a non-objective here, we want clarity and somewhat guessable syntax
12:45ChousukeI like the map approach.
12:46rhickeymaps might be a little easier on tools, they definitely are parsing this ns stuff right now, with a lot of hair-pulling
12:48scgilardiI 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:48scgilardiabsolutely regular: (prefix name opts name opts name opts)
12:49Chousukewell, '(' prefix (lib-name option-map?)+ ')' would still be very simple
12:50scgilardiI 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:51scgilardiAlso, 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:51scgilardins being declarative in English as well as intent would be a plus I think
12:55ChousukeWhy aren't dots allowed in lib names currently, anyway?
12:55cemerickrhickey: surely I don't have to point you towards AppleScript :-P
12:55cemerickbesides, this isn't about naming at all, is it?
12:55Chousukecemerick: what applescript does is called "taking it too far"
12:55Chousukecemerick: it's still important :)
12:56rhickeycemerick: it's both, use vs uses is naming, the structural stuff is not
13:39krlanyone using clojure with sesame?
13:40jackdempseyno, but sounds delicious
13:41duck11231I hadn't tried sesame, but i did some work with jena
13:41duck11231until I abandoned it to go a different way
13:41krli need a good rdf store without coding java. :)
13:43duck11231I found that I liked Jena better as a RDF store when I was evaluating both
13:43duck11231plus, jena worked better with Topbraid Composer.
13:43weissjcan someone tell me what's wrong with this (trying to process xml): (clojure.contrib.zip-filter.xml/xml-> myxml :entry)
13:43weissj1:48 jon-install=> java.lang.ClassNotFoundException: clojure.contrib.zip-filter.xml (repl-1:47)
13:44weissji need slashes?
13:44krlduck11231: what was better with jena?
13:44Chousukeweissj: that looks fine
13:45duck11231It's been so long since I looked at the two. I think I needed inferencing that sesame wouldn't give me right
13:45duck11231plus Jena was easier for me to learn
13:45weissjChousuke: do you know why i'm getting the ClassNotFoundException? isn't that code supposed to be in the contrib jar?
13:45Chousukeweissj: you probably need to require it
13:46Chousukeweissj: using the fully-qualified name to get to unimported stuff only works with java.
13:46weissjChousuke: ah
13:48weissjChousuke: (require 'clojure.contrib.zip-filter.xml) ?
13:48Chousukeyeah.
13:48duck11231Chousuke: 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:48weissj(xml-> myxml :entry)
13:48weissj1:54 jon-install=> java.lang.Exception: Unable to resolve symbol: xml-> in this context (repl-1:53)
13:48Chousukeweissj: require is not use.
13:48Chousukeweissj: after requiring, you can use the fully-qualified name :)
13:49weissjoh
13:49Chousukealternatively, (require '[clojure.contrib... :as xml]
13:49Chousuke)
13:49Chousukeand then (xml/xml-> ...)
14:19weissjok, 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:20Chouserweissj: use the functions in clojure.zip
14:25weissjChouser: 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:28Chouserhttp://paste.lisp.org/display/71471
14:29weissjChouser: thanks!
14:30Chouserif 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:31Chouserin that case (and perhaps in every case) I'd recommend you look at enlive
14:42weissjChouser: 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:48cemerickam I right in thinking that there's no var I can bind to prevent the runaway printing of circular datastructures?
14:49Chouser*print-level*
14:49Chouser,(doc *print-level*)
14:49clojurebot"; *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:51cemerickyeah, that I know about -- I was hoping to retain unlimited print-level and print IDs or something for recursively-referenced objects
14:51Chouseroh, you mean for IDerefs in particular
14:51cemerickyeah
14:52cemerickthough it's a general problem for anyone writing a print-method or print-dup impl for, say, a regular Java class
14:52Chouseror even .toString
14:52cemerickyeah
14:53Chouserthen even *print-level* doesn't help
14:54cemerickI guess I'm looking for something like #1={:foo #1#}
14:54Chouseroh. my.
14:55ChouserI guess that's not unreasonable. Does pprint do something like that?
14:55cemerickhrm, that's an idea
14:55Chouser,(let [x (java.util.HashMap.) y (java.util.HashMap.)] (.put x :y y) (.put y :x x) (.toString x))
14:55clojurebotjava.lang.StackOverflowError
14:57cemericknope, pprint doesn't help -- although it looks like the beginnings of an impl of that sort of thing is in pprint/dispatch
14:59Chouserhm, this shouldn't be hard
14:59cemerickno, one just needs to track the objects that have been visited so far
15:00ChouserIDerefs in particular
15:00Chouserids are already printed
15:01cemerickyeah, 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:03Chouserbut the latter is impossible
15:03Chouserisn't it? that's what the java.util.HashMap example above shows
15:04Chouserprint-method doesn't even get touched
15:04cemerickhrm
15:05cemerickthere's a print-dup impl for java.util.Map, but not for print-method
15:06Chouseroh, overridding .toString. hm.
15:07cemerickso, 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:07cemerickMaking this work with print-dup would require reader changes, of course.
15:07cemerickor, no, they wouldn't, nm
15:08lisppaste8Chouser pasted "prevent infinite print recursion for IDeref" at http://paste.lisp.org/display/83647
15:13cemerickChouser: ech, I'm still on v1.0, no future?
15:13cemerickThat looks about right, though
15:15Chouseroh, just take that part out
15:16lisppaste8Chouser annotated #83647 "without 'future' support" at http://paste.lisp.org/display/83647#1
15:22cemerickit works on a trivial example, but I'm still getting spews from real data. I'm trying to isolate the issue.
15:23Chouserhm...
15:23Chouseractually, binding anew at each level isn't quite what I had in mind originally
15:26cemerickhrm, actually, I think that might be a bug on my part
15:26cemerick(unsuprisingly)
15:28ChrisPS...
15:28Chouserhuh. 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:30cemerickChouser: Var.getThreadBinding, but it's package-private
15:30Chouserright
15:34lisppaste8Chouser annotated #83647 "manual binding scope, without future" at http://paste.lisp.org/display/83647#2
16:05porpoiseI 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:05porpoisewhen I restarted clojure it worked fine
16:06Chouser(use :reload 'mycode.myfile)
16:06porpoiseoh
16:06porpoiseheh thanks
16:06porpoisemaybe I should keep a noob journal and write a noob guide
16:06porpoisei'm asking enough dumb questions
16:07Chouserhttp://clojure-log.n01se.net/ is my noob guide
16:07Chousera bit wordy, I suppose
16:07porpoisecool
16:10technomancyporpoise: it's easier if you have editor integration
16:10porpoisetechnomancy: I'm using slime and emacs
16:10porpoiseis there a better integrated editor for clojure?
16:11porpoiseI was doing C-c C-l before
16:11technomancyporpoise: if you've already got slime set up, just use C-c C-k
16:11technomancyor that
16:11porpoiseC-c C-l didn't solve my problem but (reload ...) did
16:11technomancydid you do C-c C-l on the file that actually changed?
16:12porpoisetechnomancy: yes. and it prompted me whether to save and I said yes
16:12porpoiseso I thought it was weird that it didn't actually reload
16:12technomancythat's really strange
16:12porpoisemaybe my setup is screwed up
16:13porpoisedoes it work properly for you then?
16:13technomancydo you only have one slime instance running?
16:13technomancyyeah, I've never had that problem
16:13porpoisetechnomancy: I'll restart emacs to check
16:13technomancyif you can consistently reproduce it, please submit it as a bug to the clojure mailing list
16:13technomancybonus points if you can narrow it down to a simple case
16:15porpoisemaybe i'll try it on clojurebox on my windows machine as well
16:15porpoisewhat instructions should I use to setup slime and clojure? I used
16:15porpoisethe Bill Clementson script
16:15technomancyclojurebot: slime?
16:15clojurebotslime 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:16technomancyhrm; I personally heartily recommend the instructions at http://technomancy.us/126 while fully admitting that I may be biased.
16:16technomancyBill Clementson's stuff is pretty outdated.
16:17Chouserwhat's do you call the class in which a nested class is nested?
16:17Chousernot its parent class
16:17Chouserits "nestor class"
16:17j-dotouter class?
16:17technomancycontainer?
16:17cemerickouter class, usually
16:17Chouserah, thanks
16:17porpoisethe nest?
16:18cemerickis anyone aware of a NetBeans RCP wrapper for clojure (or the start of one)?
16:19weissjChouser: any hints on how to replace an xml attribute value? (xml-> z zf/descendants :foo (attr :name))
16:19weissj("hi")
16:19weissjit just returns the value, not the whole attribute. if i try to replace it with "yo" like so:
16:20weissj(zip/replace rpl (parse-str "yo"))
16:20weissj1:40 user=> org.xml.sax.SAXParseException: Content is not allowed in prolog. (repl-1:39)
16:20Chousuketried with just "yo" instead of trying to parse it?
16:20ChouserYeah, the attributes aren't children in xml-zip
16:21hiredmanlisppaste8: url?
16:21lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
16:21Chouseryou'll probably have to replace the whole element
16:22weissjChouser: how can i replace the whole element, if i only know one attribute
16:22Chouseryou'll have to not go down that far in your filter expr
16:23weissjChouser: is there a way to select the element based on its attribute?
16:23Chouseryes
16:24Chouseryou know the value you want, or just the existence of the attr?
16:24weissjChouser: value
16:24weissj(xml-> z zf/descendants :foo [(attr= :name "hi")])
16:24Chouserright
16:24weissjthat seems to select a lot more than the element
16:25lisppaste8hiredman pasted "get non-public field" at http://paste.lisp.org/display/83651
16:26hiredmanugh
16:26hiredmanmissing a paren
16:26ChousukeI like the name :P
16:26hiredman:)
16:27beutdeucequestion, how do you do if-else statements?
16:27Chouserweissj: it's a loc object
16:27weissjChouser: oh ok.. let me see if that works
16:28Chousukebeutdeuce: (if condition then-expr else-expr)
16:28Chousukebeutdeuce: see also: cond, when, if-let, condp
16:29beutdeucek
16:29weissjChouser: 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:29Chouser(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:30Chouserso beautiful and simple :-P
16:30Chouserwhy can't I annotate that paste? too old?
16:30beutdeucewhy doesnt this work => http://clojure.pastebin.com/m478e6cc
16:30weissjChouser: yeah i seem to be giving up a lot to get thread safety when i don't need it :)
16:31Chouserthe APIs just need work
16:31ChouserI have faith
16:31Chouser:-)
16:32Chousukebeutdeuce: the then and else are not part of if syntax
16:32beutdeuceoh
16:32beutdeucek
16:32Chousukebeutdeuce: also, you should not put the closing parens on their own lines
16:33Chousukethey'll feel lonely.
16:33beutdeucenow, it tells me too little arguments for if
16:33technomancyChousuke: that's the best reason I've heard yet. =)
16:33weissjbeutdeuce: you need two forms, a "then" and "else" form
16:33weissjif you're just doing an "if" with no "else", use when
16:34beutdeucek
16:34beutdeuceargh, still too few arguments => http://clojure.pastebin.com/m6c8cfe87
16:35weissjbeutdeuce: there's no "then" or "else" -
16:35beutdeuceyes there is
16:35weissjthere shouldn't be
16:35weissjexample:
16:35beutdeuceoh
16:35technomancyalso the "then" and "else" clauses need to be *inside* the last paren of the "if" clause
16:36weissj(if (= (+ 1 1) 2) (print "yep") (print "nope"))
16:36beutdeuceyeah, k , thnx
16:36Chouser,(if (= (+ 1 1) 2) (print "yep") (print "nope"))
16:36clojurebotyep
16:37beutdeucedoes clojure do null or nil ?
16:37Chousukenil
16:37Chousukewhich equals java's null
16:37beutdeucek
16:39Chousuketechnomancy: 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:39technomancyChousuke: yeah, but many people don't buy that right away
16:40porpoisetechnomancy: 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:40technomancyporpoise: clojure-mode can handle that for you actually with M-x clojure-install
16:41porpoiseoh
16:42ChousukeI 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:42beutdeuceafter i get the right output, i am constantly getting a null pointer exception, why is that? => http://clojure.pastebin.com/m66074d66
16:43Chousukebeutdeuce: you have parens around (println "true")
16:43Chousukethat means you're calling the return value of (println "true")
16:43Chousukewhich is nil
16:46arohner_is there a version of memoize out there that only memoizes the last N values?
16:48Chousukehmm
16:48ChousukeCan't think of any, but it should be fairly easy to make one
16:48arohner_yeah, I just wanted to make sure I wasn't duplicating effort
16:48Chousukefetching the memoised value would have to be O(n) though
16:49arohner_why?
16:50arohner_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:50Chousukewell, 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:50clojurebotmap is *LAZY*
16:50Chouseryou'd definitely need more bookkeeping
16:50arohner_yeah
16:51arohner_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:54Chouseryou'd probably want lru, so a lookup causes an entry to be immune from deletion for a while
16:54Chousukeyou could always do periodic "garbage collection" on the memoised map.
16:55Chouserif you had a map of args -> lookup-seq-num, that could be updated in constant time for each cache hit
16:55Chousukeyeah. then go through it every once in a while and remove entries from the actual memorised map that are too old
16:55Chouserbut then on insert you'd have to O(1) walk that map looking for low-numbered values
16:58porpoiseI 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:58porpoisePreviously I was directly editing slime's invocation of java
16:59Chousukeswank-clojure-extra-jar-paths or something?
16:59Chousukeit's in the customize group for swank-clojure
17:01porpoisethanks
17:02lisppaste8hiredman annotated #83651 "wall-hack-method" at http://paste.lisp.org/display/83651#1
17:02technomancyporpoise: 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:04beutdeuceChousuke: if i remove parens around println "True", it says if has too many args
17:10technomancybeutdeuce: remove just one pair of parens
17:11beutdeucetechnomancy: still says too many args:
17:11beutdeuce(defn elem
17:11beutdeuce [x xs]
17:11beutdeuce (if (= x (first xs) )
17:11beutdeuce print "True"
17:11beutdeuce (if (= (rest xs) nil) print "False" ((elem x (rest xs))))))
17:12technomancybeutdeuce: you removed two levels of parens around print "True"
17:13technomancyalso you didn't put it inside the if expression like I said
17:13beutdeucecould u please paste the right version, i'm a bit confused right now
17:13technomancysure, but I think you might want to take a step back and try reading some more existing code before you proceed.
17:15technomancyhere's the working version: http://clojure.pastebin.com/m1cbcfc5f
17:17beutdeucei appreciate your help
17:17technomancynp; I hope you get things figured out
17:17beutdeucesay, is ther infix notation on clojure, like in haskell `` ?
17:17Chousukeno
17:17hiredmanugh
17:17beutdeucek
17:20Chousukebeutdeuce: 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:20Chousukeis considered an "operator" and the rest are the arguments; so, the list form evaluates to whatever that operator called with the arguments returns.
17:20Chousukebeutdeuce: further, there are macros and special forms which can "bend" the rules a bit.
17:21mariorzwhat should I use to parse a huge xml file without loading the whole thing to memory?
17:22Chousermariorz: you can try clojure.contrib.lazy-xml
17:22mariorzChouser: cool
17:22Chouserbut it's pretty easy to accidentally bring in the whole thing
17:23ChouserI'd be interested to know how it works out for you.
17:23mariorzwhy accidentally?
17:23Chousukebeutdeuce: 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:24Chousermariorz: if you have <doc><t1>...10GB of nested data...</t1><t2>foo</t2></doc>
17:24Chousermariorz: ...and you ask for doc's second child, the whole thing gets parsed
17:24beutdeuceChousuke: k
17:25mariorzChouser: makes sense, ill let you know how it owrks out
17:25Chousukebeutdeuce: 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:26beutdeuceah
17:27Chousukebeutdeuce: as if only takes three arguments, each of the result branches can only contain one form.
17:28beutdeucemakes sense
17:28Chousukebeutdeuce: 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:28beutdeucei see, like Haskell
17:28beutdeucequestion, 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:29Chousukeso (if true (do (print "1") (print "2")) (print "not true"))
17:29beutdeuceyeah
17:30Chousukebeutdeuce: usually, you want to declare a namespace at the top of your file
17:30Chousukebeutdeuce: but you can also use (load "foo") (no .clj) to just "include" a file
17:31beutdeuceChousuke: cool thanks. i g2g for now. Thanks for all the help. and technomancy.
17:47hiredmanI am always surprised when I see people who are obviously unfamiliar with clojure doing performance testing
17:48hiredmanit seems to imply performance is the first thing people look at
17:48hiredmanwhich is at odds with, well, me
17:48Chouserheh
17:51mariorzChouser: 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:52Chouserthat's the idea
17:53mariorzcool
17:56mariorzi dont think its working
17:56mariorzjust calling trim-space on the file makes me run out of heap space
17:56mariorzer parse-trim
17:56Chouser:-(
17:57Chouserwhat are you doing with the result of parse-trim?
17:58mariorzassigning it to a var
17:58Chouserbah. that ought to be safe.
17:58mariorz(def foo (parse-trim "bigfile))
17:59fsodomkaChouser: logging at http://clojure-log.n01se.net/ doesn't work recently for me
18:00Chousermariorz: try (parse-seq "bigfile" startparse-sax 1)
18:02mariorzChouser: cool, i think that works
18:03Chousermariorz: ok. without that it was going ahead in the background trying to parse the whole thing.
18:03ChouserSo I essentially lied to you before. :-P sorry.
18:03mariorzhah np
18:04Chouserfsodomka: bleh. indeed. thanks.
18:05Chouserfsodomka: can't fix it tonight. I'll try to get to it soon.
18:05ChouserI've got the logs, but they're in the wrong format, so once its fixed the intervening days should show up
18:05mariorzChouser: those this mean i could use parse-trim as well as long as i suply startparse-sax?
18:06mariorzs/those/does/
18:06fsodomkaChouser: cool, looking forward to it
18:06Chouserno, it's the 1 that matters
18:06fsodomkaChouser: thanks!
18:06Chouserthat tells the parsing thread how far ahead of the consumer it's allowed to get
18:07mariorzChouser: ok, startparse-sax is the default aprser anyway?
18:07Chouseroh, yes -- (parse-trim "bigfile" startparse-sax 1)
18:07Chouseryes, startparse-sax is the default
18:07mariorzcool, thanks for the help!
18:08Chouserthe pull-parser is better, but requires another jar: http://www.extreme.indiana.edu/xgws/xsoap/xpp/
18:09Chouserhuh. 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:10mariorzwhy?
18:11mariorzit automatically sets a queue size?
18:12mariorzah i see
18:12mariorzIf no parser
18:12mariorz is specified and org.xmlpull.v1.XmlPullParser is in the classpath,
18:12mariorz this superior pull parser will be used."
18:15westajayis there a simpler api function for testing if all elements in a collection are true?
18:15westajayother than doing this
18:15westajay(every? (fn[x] x) [true true true])
18:16Chousukewestajay: there's the "identity" function
18:17scgilardi(every? true? a-collection) (if you mean literally true and not just non-nil and non-false)
18:18westajayscgilardi: that works
18:19westajaythank you sir
18:19scgilardiwestajay: you're welcome :)
18:20Raynes-,(true? (true? (true? true)))
18:20clojurebottrue
18:20Raynes-True!
18:21scgilardiChousuke: 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:22scgilardi[ 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:24scgilardiBefore it was simplified, one could use the prefix list concept nested arbitrarily deeply: (:use (clojure (contrib sql (sql test))))
18:24hiredmanclojurebot: CA?
18:24clojurebotCA is Contributor Agreement: http://clojure.org/contributing
18:29Raynes-I wish I had a printer, so I could print that. :(
18:30Raynes-I'd buy one, but hiredman took all my moneys.
18:31hiredmanall the money you where going to get paid for NPEs
18:31scgilardigiven his recent demise, at least that's one problem you won't have any more
18:31scgilardihey!
18:42ModiusIs clojure's "doall" a function or a macro?
18:43hiredman,(meta #'doall)
18:43clojurebot{: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:43ModiusDoes that mean it is a function?
18:43hiredman,(meta #'defn)
18:43clojurebot{: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:43hiredmanyes
18:44hiredmanif it is a macro there iwll be a :macro true
18:46scgilardi,(doc doc)
18:46clojurebot"([name]); Prints documentation for a var or special form given its name"
18:46scgilardiclojurebot has a custom doc func?
18:47hiredmanyes
18:47hiredmanwell, custom doc macro
18:47scgilardiright. is it to minimize lines of output or to solve some security problem?
18:48hiredmanwell, the way doc prints out stuff is not irc friendly
18:48hiredmanthe dashes, the spaces, etc
18:49scgilardimakes sense. clojure.core/doc also prints out "Macro" for macros.
18:49hiredmanoh really
18:49hiredmanhow useful
18:55beutdeuceif i have a fun.clj file with (ns "lib") at the top, can i use (in-ns "lib") from Repl to load it?
18:57hiredmanno
18:57Raynes-You could just load the file.
18:57hiredmannamespace names are symbols
18:57beutdeucehow?
18:57hiredmannot strings
18:57hiredman(ns lib)
18:57hiredman(in-ns lib)
18:58hiredmanand in-ns does not load anything
18:58hiredmanit jsut switches to another namespace
18:58beutdeucehow would i be able to load an external clj file?
18:58hiredmanyou can just one of the load functions or require or use
18:58Raynesbeutdeuce: (load "path")
18:58Rayneshiredman: I win.
18:59beutdeucedoesnt work
18:59beutdeucetells my no source file
19:00Raynesbeutdeuce: It has to be on your classpath, by the way.
19:00RaynesI think.
19:00beutdeuceis there any alternative way?
19:00RaynesRequire or use, but it still has to be on the classpath.
19:01RaynesOnce again, I think. I never have to do stuff like this. I use Slime.
19:01beutdeucehmm. whats that?
19:02beutdeuceworks with clojure?
19:03RaynesIt'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:03Raynes-cp adds whatever directories you specify to the classpath.
19:03RaynesFor example: java -cp /home/rayne/clojure:/home/rayne/clojure2 -jar clojure.jar
19:04RaynesAnything in Clojure and Clojure 2 will be on the classpath.
19:04RaynesI don't know enough about the classpath to really /explain/ it, I just know how to use it.
19:04RaynesIf anyone else can explain it better, feel free to step in. :)
19:05beutdeucethats clear enough
19:05beutdeucewhats slime though?
19:05RaynesIt's an Emacs mode for Lisp.
19:05RaynesMost people use it and clojure-mode+clojure-swank for their clojure editing needs.
19:06technomancybeutdeuce: there's an explanation/tutorial at http://technomancy.us/126
19:06Raynestechnomancy: Thank you. I was scared to death he was going to ask something more complex about Slime. :|
19:07beutdeuce:P
19:09technomancyhehe
19:10lisppaste8mariorz pasted "untitled" at http://paste.lisp.org/display/83661
19:10mariorzChouser: still around?
19:10beutdeucei'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:11technomancybeutdeuce: if you read the article I linked to, you shouldn't have to configure that stuff by hand
19:12beutdeuceworks with mac?
19:23technomancybeutdeuce: others have reported success
19:23technomancycan't test myself
19:23beutdeucetechnomancy: nothing happens when i do M-x package-list-packages
19:26technomancybeutdeuce: you've triggered an obscure elpa bug I've been unable to reproduce. =\
19:26technomancytry restarting Emacs; if that doesn't help, rm -rf the elpa directory inside your .emacs.d and try again
19:26beutdeuceemacs-starter-kit in currently in ~/.emacs.d/emacs-starter-kit
19:26beutdeuceit should work
19:27KnekkSorry, I missed the top of the discussion. This is for setting Emacs for Clojure?
19:28beutdeuceKnekk: yeah, trying to get emacs-starter-kit to work
19:28Knekkbeutdeuce: where can I download that?
19:28beutdeuceKnekk: http://technomancy.us/126
19:28technomancybeutdeuce: emacs-starter-kit should actually be just ~/.emacs.d rather than nested inside it
19:29beutdeuceoh
19:30beutdeucenice, seemed to work now
19:30beutdeucewoa, this is amazign
19:36technomancyyay =)
19:45beutdeucei'm getting trouble loading slime after emacs restarts
19:48technomancybeutdeuce: does it work after you open a .clj file?
19:48beutdeucei 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:51beutdeuceargh, didnt work
19:51beutdeuceits as if it doesnt recall slime after i restart emacs
19:52technomancyinit.el is the equivalent of .emacs
19:52beutdeucei put it there, but then it gave me an error
19:53beutdeucewhen i take that line out, it works again, just not slime
19:53technomancycan you paste the error?
19:54beutdeuceit flashes quickly then emacs loads to default gnu screen
19:55technomancyright; if you switch to the *Messages* buffer you can see the error
19:56beutdeucedoes it matter where i put: (eval-after-load 'clojure-mode '(clojure-slime-config)) ?
19:56technomancyif you're using the starter kit, put it in a file in .emacs.d named after your username + .el
19:56technomancythat way you won't get merge conflicts if you update to a newer version of the starter kit
19:57beutdeucewell, no error, but M-x slime doesnt work
19:57beutdeuceoh eait
19:57beutdeucewrong dir
19:57beutdeuceh/o
19:58beutdeuceyeah
19:58beutdeucestill no slime
19:58beutdeucedo i have to load username.el manually?
19:58beutdeuceits in my .emacs.d/currently
19:59technomancyno, that happens for you
20:00technomancytry M-x slime after you've opened a .clj file
20:00beutdeuce(eval-after-load 'clojure-mode '(clojure-slime-config)) is whats in there, should i try to run that in emacs itself?
20:00technomancyno, you don't need to load it manually
20:01beutdeucetechnomancy: yeah, it only works when i load a .clj file, is there a way to get it work without loading a clj file?
20:02technomancybeutdeuce: try just putting in (clojure-slime-config) instead of (eval-after-load [...])
20:02beutdeucemakes sense, i'll try
20:02technomancyrecent versions do this, but my packages haven't been uploaded to elpa yet. =\
20:04beutdeuceyep now works, thanks for all your help!
20:05technomancyno problem
20:12spaceman_stuHi 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:22gstampspaceman_stu: maybe you need to include the xerces library?
20:25spaceman_stugstamp: 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:28hiredmanman, almost everything is a reader macro
20:37skalnikAnyone know of a good resource for Ruby programmers looking to play with Clojure?
20:40ataggart,(if (Boolean. "false") :weird :ok)
20:40clojurebot:weird
20:42Anniepooskalnik, I'm learning from Stuart Halloway, Programming Clojure, it's pretty good
20:42skalnikI'll look into it, thanks.
20:42skalnikAh, pragprog. Must be good :)
20:42Chousukeataggart: I think you're supposed to use Boolean/valueOf :)
20:43ataggartit's good, though it helps to know a bit of java
20:43Anniepooit shares the usual pragmatic problem of being more boosterish than actually informative
20:43ataggartchousuke: I know, just testing it out as osmeone brought it up on reddit
20:43RaynesAnniepoo: It's pretty informative regardless.
20:43ChousukeMaking your own Boolean instances is weird anyway :P
20:44Anniepooyes, agree
20:44ChousukeI wonder why it's even supported
20:44RaynesIt's more of a "pump you up and get you going tutorial!" than a endless pit of knowledge.
20:44RaynesBut Clojure is a Lisp. There just really isn't all that much to talk about. The proof is in the kodak.
20:45mariorzdoes map make use of seperate threads?
20:46Chousukeno
20:46Chousukethere's pmap for parallel mapping.
20:46mariorzim having a weird error where calling map returns a transaction not in thread error
20:47Chousermap is lazy
20:47mariorzmapping a function to a persitnat list
20:47mariorzno, it is but im trying out with a normal list
20:47Chouserbut what map returns is lazy regardless
20:48Chouserif map is called inside a dosync, but what it returns gets passed to outside the dosync, you're likely to have problems
20:49Anniepoosorry Raynes, I got distracted by RL, yes, I'd agree with you.
20:49Anniepoomy complaint is only that at times I feel like, in common with all the PP series, it sacrifices
20:50Anniepooclarity in elucidating some boring but vital part of the language for an 'ooh wow, isn't that cool' demo
20:51Anniepoobut that aside, it's a pretty clear intro to the language, esp. if you're not coming from another functional language
20:54RaynesI've never read a pragprog book.
20:54RaynesI generally stick to O'Riley books.
20:54AnniepooI've read many, they all have this same problem.
20:55AnniepooO'Riley used to be God, they seem to have let a lot of fluff in at some point
20:56mariorzChouser: http://paste.lisp.org/display/83670
20:56mariorzthats what i mean
20:56RaynesReal World Haskell is a good, comprehensive book. But it's amazing the amount of stuff they managed to screw up in it.
20:56arohner_Raynes: what did they screw up in RWH?
20:57arohner_I have the book, but I"m not a haskell expert and I didn't read it carefully
20:57Raynesarohner_: 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:58RaynesBut it still manages to be a very good read.
20:58arohner_I got it mainly to read about what was different in haskell rather than a serious attempt to learn it
20:59Raynesarohner_: You could have just read it online, if that was the case.
20:59Chousermariorz: yeah, try wrapping your (map ...) in a (doall ...)
21:00mariorzChouser: coolness, i get it now
21:00mariorzi.e. what you meant with map returns lazy
21:01AnniepooI've found one error in Halloway, and it's a trivial one
21:02AnniepooYou know, I'm also having to deal with building a big C# library today, and the difference is truly breathtaking
21:02hiredmanChouser: do you know of a no-op reader macro off hand?
21:03Chouser#_
21:03Chouseror what do you mean by no-op?
21:03Chousermariorz: right
21:03hiredmanChouser: dunno
21:03hiredman //no op macros return the reader
21:04Chouser,[1 2 3 #_ 4 5 6]
21:04clojurebot[1 2 3 5 6]
21:04hiredmanfrom LispReader
21:05Chouserhm -- a reader macro can use thre reader obj as a sentinel, looks like.
21:06hiredmanhiredman.reader=> (eval (my-read))
21:06hiredman(+ 1 2)
21:06hiredman3
21:06clojurebot3
21:06Chouserah, a comment
21:06Chouser; is a reader macro
21:06hiredmanChouser: I see
21:07ChouserCommentReader.invoke() walks to the end of the line, then returns the reader as a sentinel that no form has actually been produced yet
21:08Chouserlooks like #_ may be the only other one. It reads the following form and likewise indicates nothing has been read yet
21:08Chouser,(read-string "; foo")
21:08clojurebotjava.lang.RuntimeException: java.lang.Exception: EOF while reading
21:08Chouser,(read-string "; foo\n5")
21:08clojurebot5
21:09mariorz:(
21:09mariorzim still running out of heap space
21:10Chouseryou can make your heap bigger when you launch java
21:10mariorzbut it should not be loading the whole file to mem this way, right?
21:11Chouseryou're walking all the way to the end of the xml file?
21:11Chouseror do you stop early?
21:11mariorzall the way
21:11mariorzhttp://paste.lisp.org/display/83670#1
21:11Chouserhm... that may be the problem...
21:12mariorzhow so?
21:12Chouseras in, the whole file is not loaded at the beginning, but it's probably all cached
21:12Chouserso if you don't bail early, it may all end up in memory after all...
21:13mariorzwhat do you mean bail early?
21:13mariorzlike jsut parse the first x elements ?
21:14ChouserRight. The normal clojure.xml/parse parses the whole file before it even returns.
21:15Chouserbut 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:15Chouserhang on, gotta put a kid to bed. back in a few.
21:15mariorzk
21:20mariorzshouldnt the cache have a max size so this doesnt happen though?
21:25RaynesHow cute. Chouser has minicoders.
21:30mariorzmemory usage for the java process never seems to go up though
21:30mariorzjust cpu
21:30arohner_right, java has a limit on how much ram it will take
21:30Chousermariorz: it's the regular lazy seq caching -- each cell caches it's own value, there's no global view.
21:31mariorzbut that low?
21:31mariorzaround 90mb
21:31Chouserthe solution is to make sure that you release earlier head(s) of the seq(s) as you walk through.
21:32mariorzthe seq returned by the map right?
21:32mariorzChouser: how do i do that?
21:32Chouserbut if you're walking through (:content node), the node map is hanging onto the head so it must all end up in memory
21:32RaynesChouser: How many minicoders do you have?
21:32Chousernone coding yet. :-)
21:33Raynes:)
21:34mariorzso 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:34Chouseryes
21:35Chouserand 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:35Chouseroh!
21:35Chouserare you throwing away the return value of the map?
21:35mariorzso what would be a way around that? :)
21:35Chousersave_node is about side-effects?
21:36mariorzwell it stores the node value in a db
21:36Chouserright -- you don't care about the return value of save_node, right?
21:36mariorznope
21:37Chouserok, then you should use (dorun (map ...)) or better yet (doseq ...) inside your with-tx
21:37Chouserwell, I should warn you that I'm not sure it's possible to get what you want without restructuring lazy-xml itself
21:38Chouserbut it might be. And even if lazy-xml is doing the right thing, using (doall (map ...)) would thwart it.
21:39mariorzfrom the api docs it would seem doseq is what i want no?
21:39Chouseryes
21:41mariorzsame error
21:41Chouseryes.
21:42mariorzbut why?
21:43Chousernow, 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:44Chouserafter 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:46mariorzdidnt really understand that
21:47Chouserok, let's look at a simpler example
21:47Chouser(let [x (map #(str "A number: " %) (range 1e7))] (last x))
21:47Chouserx is a very long lazy seq of strings.
21:47ChouserI say "is" but more accurate would of course be to say "promises to be"
21:48mariorzright
21:48mariorzbecuae its lazy
21:48ChouserRight. Now, (last x) has to walk to the end of the seq and return the final item.
21:48Chouseras shown above, this will happen fairly quickly and return the result.
21:48Chouser,(let [x (map #(str "A number: " %) (range 1e7))] (last x))
21:48clojurebotExecution Timed Out
21:48Chouserhm, not so quickly.
21:51Chouserwell, anyway, it should work in your repl, returning a string after a few seconds
21:51mariorzright
21:51Chouserit 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:51gkoHello... How to check if an element is in a list?
21:52Chousergko: perhaps a set would work better?
21:52Chousermariorz: but one small change breaks it:
21:53gkoOh: ((set my-list) 1)
21:53hiredmangrrr
21:53Chousergko: 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:54Chouser(let [x (map #(str "A number: " %) (range 1e7))] [(first x) (last x)])
21:55gkoChouser: it was just a general question... I have already been using sets because of this...
21:55Chousermariorz: 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:56Chousergko: ah.
21:56Chouser,(.contains '(a b c) 'b)
21:56clojurebottrue
21:57gko(set 1 2 3)
21:57mariorzChouser: ok, and this happens within lazy-xml becuase it maintains a pointer to the head of the document?
21:57Chousermariorz: right. bigfile points to the whole document
21:58ataggart~some
21:58clojurebotHello, gnuvince
21:58ataggart(doc some)
21:58clojurebot"([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:58Chousermariorz: I'm looking at lazy-xml's code to see if i can spot any head-retaining there, but I'm not sure...
21:58Chousermariorz: so anyway, the next thing that is necessary (but perhaps not yet sufficient) is to not store bigfile globally.
21:59ataggartgko: use some
21:59gkoataggart: ?
21:59ataggart(doc some)
21:59clojurebot"([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:59mariorzChouser: just something like (with-tx (doall (map save_node (:content (parse-trim "file.xml" startparse-sax 1)))))
22:00mariorz?
22:00mariorzChouser: using xpp would not help with this right?
22:01Chousermariorz: try (with-tx (let [bigfile ...] (doseq [node (:content bigfile)] (save_node node)) ...
22:01Chousermariorz: or what you had (but with dorun instead of doall)
22:02Chousermariorz: 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:02mariorzdoseq or dorun?
22:02ChouserI prefer doseq. It's your choice.
22:02Chouserboth return nil which is the critical thing
22:02mariorzk
22:03mariorzthx again for the help, going for a bite and will mess aorund some more later
22:03gkoataggart: Oh OK... any reason why lists are not functions like maps or sets?
22:04ataggartin what sense?
22:04Chousermariorz: ok
22:04gko(my-map key) => value
22:04ataggartgko: ah because sets and maps have O(1) access on their keys
22:04ataggartso they can act as functions
22:05ataggartcontains? only works on keys, which lists dont have
22:05gkoataggart: right...
22:05ataggart(contains? [:a :b :c] 2)
22:05ataggart,(contains? [:a :b :c] 2)
22:05clojurebottrue
22:06ataggartif you want to spin through a list, you can do it with some
22:06Chouser,(some #{'c} '(a b c))
22:06clojurebotc
22:07gkowhy , in front of your samples?
22:07ataggartit tells clojurebot to execute it
22:07ataggartthough it sometimes excutes code anyway
22:08ataggartit's feisty
22:08gko,1
22:08clojurebot1
22:08gko:)
22:08gkocouldn't clojurebot puts the evaluated expression?
22:09gkothat's nice
22:11ataggart~botsnack
22:11clojurebotthanks; that was delicious. (nom nom nom)
22:25hiredmando clojure's tests include reader tests?
22:30arohner_hiredman: some
22:30arohner_there's a clojure.test-clojure.reader ns
22:31arohner_it's hardly comprehensive
22:31hiredmanwell
22:32hiredmanmy wrapper around LispReader passes that, so it's time to start replacing bits and pieces
22:32arohner_what are you working on?
22:33hiredmanreplacing Lispreader.java with clojure code
22:34arohner_cool
22:34hiredmanhttp://github.com/hiredman/reader/blob/afb9e6266358fc965c9572a1cafc57dc15908e42/hiredman/reader.clj
22:50arohner_sigh. Why does java provide SimpleDateFormat, and then not provide constants for really common date formats, like RFC 822 and ISO8601?
23:23durka421why doesn't clojure support java variadic methods (like PrintWriter/printf) without to-array?
23:35arohner_durka42: java variadic methods are sugar for "normal" functions that take arrays
23:35durka42i suppose there's no way for clojure to detect them without reflection
23:35durka42or maybe even with the use of reflection
23:36durka42i know they take arrays, hence my (slight) annoyance at having to play with to-array
23:45durka42i had caps lock and couldn't figure out what the _hell_ vim was doing
23:45slaneyheh
23:45slaneyI have done that
23:46slaneymore than once
23:46slaneyadl
23:46slaneysadly