#clojure log - Aug 31 2011

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

0:14 chewbranca: what's the recommended lib for interacting with sql? (sqlite and postgres)

0:19 gstamp: I'm not sure what's recommended by you can find a list of them here: http://clojure-libraries.appspot.com/category/136007

0:19 srid: which clojure resource/book would you recommend to *thoroughly* learn clojure and its standard library functions?

0:19 akin to 'python in a nutshell' that I used for python back in 2003

0:20 chewbranca: gstamp: ahh cool, haven't seen that site before, was using clojure-toolbox.com

0:20 gstamp: I try to keep it fairly up-to-date

0:21 chewbranca: the clojure.contrib.sql (now: https://github.com/clojure/java.jdbc) appears to be the most widely used (or blogged about and found by google), but is lacking in docs and examples compared to https://github.com/LauJensen/clojureql

0:22 amalloy: srid: try again, but don't put "nutshell" and "thorough" in the same sentence?

0:22 chewbranca: gstamp: well done! glad to see another site with a variety of clojure resources

0:22 srid: http://java.ociweb.com/mark/clojure/article.html that's a good place to start (at least I've found it useful and up to date)

0:23 amalloy: anyway, the only way to become thoroughly familiar with clojure and its standard libraries to write a lot of clojure and (just as important) read a lot of clojure

0:24 srid: what do you mean "read a lot of clojure"?

0:24 chewbranca: srid: read source code of good projects

0:25 amalloy: not even good projects. i mean, sure, prefer good projects

0:25 just read source code of any clojure program. you'll learn something

0:25 chewbranca: amalloy: very true

0:28 ddwwk_: evenin'

0:30 where are the irc logs kept?

0:31 n01se

0:31 got it

0:31 chewbranca: gstamp: hey for the editing section, I want to give a shoutout to slimv (https://github.com/vim-scripts/slimv.vim) which is awesome, swank client in vim with a nice paredit plugin as well

0:35 polypus74: chewbranca: ty for tip. paredit definitely an incentive to learn vim

0:35 chewbranca: polypus74: well slimv is a port of slime for emacs, so as much as I love vim, emacs is probably better to learn in regards to clojure/lisp if you don't know either yet

0:36 polypus74: already on emacs/paredit, but i like the vim philosophy better. no paredit was a real downer, until your post that is

0:37 chewbranca: polypus74: oh cool! well in that case, slimv rocks, works great with swank-clojure, gives you a repl directly in vim and the paredit support works well

0:37 gstamp: chewbranca: feel free (or I'm happy to edit it if you don't have a google login)

0:38 chewbranca: gstamp: oh cool, yeah I can add that in

0:49 gstamp: http://clojure-libraries.appspot.com/show/141002

0:51 gstamp: chewbranca: thanks!

0:51 chewbranca: gstamp: no problem, good job on the site!

1:28 amcnamara: amalloy_: any idea what would cause java.util.concurrent.RejectedExecutionException when running 4clojure locally? something to do with clojail permissions perhaps?

1:28 exception is thrown on all page loads

1:28 accel_: is there any clojure addon taht allows static typing?

1:30 scottj: accel_: no, there's a logic tutorial that explores static typing and there's the potential for clojurescript to someday use google closure's static type checking

1:30 amcnamara: accel_: you can use type hints though, not static but improve performance slightly

1:31 scottj: and there's a defn macro that lets you automatically add pre/posts based checking types

1:33 accel_: i care less about performance

1:33 and more about finding bugs at compile time

1:42 amcnamara: accel_: you can try asserting against a type, but I'm not sure how idiomatic that is

1:49 tomoj: wouldn't be at compile time anyway?

1:52 khaliG: just got my copy of Joy of Clojure, looks great. Is it intended to be read from cover to cover or as a reference?

2:13 jblomo: is prxml being released for 1.3.0?

2:18 scottj: CL library that claims to be almost as good as gclosure https://github.com/mishoo/cl-uglify-js

4:07 kzar: ,(apply or [true true false]) <- How can I do something like that?

4:07 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(NO_SOURCE_PATH:0)>

4:08 opqdonut: kzar: (defn orf [x y] (or x y))

4:08 kzar: opqdonut: Oh and then reduce right?

4:09 opqdonut: but also, ##(some identity [true true false])

4:09 lazybot: ⇒ true

4:10 opqdonut: and, ##(every? identity [true true false])

4:10 lazybot: ⇒ false

4:10 opqdonut: those are the equivalents of apply or and apply and

4:11 kzar: opqdonut: Gotya thanks

5:30 clgv: Is there any support in leiningen to "lein deps && lein install" multiple projects that form a dependency tree with one leiningen command?

6:04 "lein sub" seems promising

7:52 kumarshantanu: clgv: There is a lein-sub plugin

7:53 which will have much better support in Leiningen 2.0

7:53 clgv: kumarshantanu: yes thats what I found before ;)

7:53 but indeed I need something different like "build all checkouts"

7:54 and that has to be recursively and build each only once

7:54 kumarshantanu: clgv: In lein 2.0 you can specify fine-grained chain of actions

7:54 michaelr525: Hello!

7:54 kumarshantanu: But that is not ready yet

7:55 clgv: ah ok. I hope they adjust the deletion so that .gitignore files (or "hidden linux files") are not deleted

7:56 kumarshantanu: clgv: Can you file a bug to have it on the collective TODO list?

7:58 clgv: kumarshantanu: not really. a github account is needed for it, it seems

8:00 kumarshantanu: clgv: Okay, so the error description is something like "`lein clean` should not remove the hidden (beginning with a period) files"?

8:00 I can file the bug

8:00 clgv: kumarshantanu: yes. but it's not only lein clean. lein deps also deletes them

8:01 kumarshantanu: clean deletes them in classes/ and deps in lib/

8:04 kumarshantanu: clgv: Right, I can reproduce the bug -- however, I have a question

8:05 Why would you keep anything in "lib" or "classes"? They may not be required to put in version control at all

8:07 clgv: Eclipse/CCW does not create them when they are missing, so it is annoying to have to create them after a "git clone"

8:08 lnostdal_: i've probably asked this a couple of times, but how does one go about getting slime to catch this exception: (.start (Thread. (fn [] (/ 42 0)))) ? .. it ends up "outside" of slime now, back in the terminal where `lein swank' was started

8:09 kumarshantanu: clgv: It seems you need this fixed for a development workflow you follow -- can you share what is your workflow? Is "classes" or "lib/*" on your Eclipse project classpath?

8:09 clgv: "lib/*" is. I am currently changing my workfolow a bit.

8:10 "classes" is as well

9:27 michaelr525: sleepy@work

9:27 maybe it's an idea for a website

9:27 clgv: a blog ;)

9:27 michaelr525: sleepyTube.com

9:27 :)

9:28 wake me up before you go go

9:31 bsteuber: what's the most common clojure css generating solution?

9:33 st3fan: bsteuber: 'vi main.css' ? :)

9:35 Raynes: bsteuber: Marginalia has a nice little css generator.

9:37 bsteuber: found gaka and cssgen so far

9:37 as stand-alone libe

9:41 thorwil: bsteuber: a recent announcement of https://github.com/rathwell/clj-style mentioned gaka, cssgen, and csslj

9:44 bsteuber: thanks

10:15 cees_: Hi, does anyone now a gracefull way to get out of a clojure program that parses a stream of input commands via (doseq [c (BufferedReader. *in*)] (processCommand c)?

10:15 Of course I can press ^D or ^C, but that kills my clojure.repl too.

10:16 joegallo: loop/recur instead of doseq and have a special "quit" command where you don't recur?

10:17 (when (not= c "quit") (processCommand c) (recur ...)

10:17 cees_: Joegallo Thanks, that sound simple. Should have thought of it myself :-)

10:42 arohner: how do I convert a j.u.Vector to a seq?

10:45 polypus74: arohner: just calling seq on it should do the trick

10:45 arohner: polypus74: I'm getting "Don't know how to create ISeq from: java.util.Vector$1"

10:46 clgv: it already "is a seq" - see ##(map inc (java.util.Vector. (range 10)))

10:46 lazybot: ⇒ (1 2 3 4 5 6 7 8 9 10)

10:46 joegallo: it seems like you aren't passing in a vector, then, but some anonymous class defined inside the vector class (hence the $1)

10:47 are you sure it's a Vector?

10:49 somebody is calling elements somewhere, Vector$1 is the anonymous Enumeration class defined inside Vector

10:49 if you want to keep the rest of the code as is, use enumeration-seq, i guess

10:50 arohner: joegallo: that did it, thanks

11:00 gtrak: is there a way to manually fail a test in clojure.test?

11:04 dakrone: gtrak: (is false)

11:05 gtrak: dakrone, i can put that anywhere within the body?

11:05 dakrone: yep

12:48 srid: amalloy_: (replying to yesterday's message) how did you personally learn clojure?

12:50 hugod: anyone else notice that :gen-class doesn't statically resolve protected method calls on the class it is extending?

12:53 ejackson: hugod: I know it doesn't extend final

12:53 that kicked me about for a little while

13:03 llasram: Convention question: what's the most idiomatic way of expressing something needing both initialization and finalization?

13:03 Like `with-open' handles objects which need to be .close'd when they leave scope, but with custom behavior.

13:03 What I have right now is `open' & `close' functions and a `with-foo' macro which takes a binding form of [name args-to-open]. It just looks a little sloppy to me because `name' isn't literally bound to `args', but `(open args)'

13:09 khaliG: Is there any project for adding a loop feature to the language?

13:12 technomancy: one loop feature's not good enough for ya?

13:15 joly: ,(doc loop)

13:15 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."

13:15 khaliG: technomancy, no i mean a real loop :)

13:16 llasram: khaliG: How is that not a real loop?

13:16 khaliG: see http://www.ccs.neu.edu/home/shivers/papers/loop.pdf and http://video.google.com/videoplay?docid=-3704713569771882785

13:18 hiredman: khaliG: common lisp's loop is seen as not abstract enough

13:18 or not declaritive enough I guess

13:18 because you can't parallelize it

13:19 khaliG: yeah and CL:LOOP involves mutation of loop variables

13:19 but i think Olin shows how to do make a functional one which would fit clojure perhaps

13:19 llasram: What about clojure's for/doseq? Not the same syntax, but it looks like you con do similar stuff

13:21 khaliG: yea that's handy sometimes but still fairly limited imho

13:22 llasram: What's something that the cl:loop makes easier?

13:22 Vinzent: I saw clj-iter somewhere ob github...

13:24 khaliG: Vinzent, thank you, i'm a fan of iterate :)

13:25 sweet that's exactly what i was looking for!

13:28 Vinzent: khaliG, it'd be cool to add it to the new contrib, wdyt?

13:29 khaliG: would be cool indeed

13:31 Vinzent, would be nice too if clj-iter did code-walking too

13:32 chewbranca: technomancy: fun bbq script, worked like a charm

13:35 technomancy: chewbranca: hehe; awesome

13:47 amalloy: amcnamara: broken version of lein

13:50 srid: i read JoC, and then wrote and read a bunch of clojure

13:50 and hung out in #clojure a lot, asking and answering questions

14:11 gtrak`: how would i check that the input is a bytearray?

14:13 opqdonut: you mean a byte[]?

14:13 say (instance? (something Byte/CLASS) x)

14:13 I'm trying to remember what "something" was :)

14:14 amalloy: &(Class/forName "[B")

14:14 lazybot: ⇒ [B

14:14 amalloy: &(instance? (Class/forName "[B") (byte-array 0))

14:14 lazybot: ⇒ true

14:14 opqdonut: oh, that's good

14:15 but there's something like: &(instance? (.getClass (java.lang.reflect.Array/newInstance Byte/CLASS 1)) (byte-array 0))

14:15 gah

14:16 ,(instance? (.getClass (java.lang.reflect.Array/newInstance Byte/TYPE 1)) (byte-array 0))

14:16 clojurebot: true

14:16 gtrak`: ah....

14:17 amalloy: opqdonut: j.l.r.Array/newInstance is like thirty times more verbose than make-array or into-array

14:17 opqdonut: ISTR there being something that gave the array class when given the element class

14:17 gtrak`: that's really complicated

14:17 opqdonut: yeah, amalloy's solution is fine

14:17 amalloy: but i don't see anything in j.l.reflect or j.l.Class that would turn Foo.class into Foo[].class

14:18 opqdonut: yeah. something that I found with google actually says getClass+newInstance is the canonical generic way of doing that

14:20 amalloy: it probably is, although i bet apache commons has something better

14:23 i've apparently lost the ability to compile and run simple java apps from the CLI

14:23 xicubed: i am starting out. i got "lein ring server" to run but how do I stop it? Ctrl-z gets me back to the shell but if I run it again the port is taken.

14:23 r9: @xicubed: ctrl-z suspends a process

14:24 amalloy: ah, no. just forgot my package declaration. anyway, it looks like java can use the nice syntax `byte[].class` for literals

14:24 r9: try "fg"

14:24 that will bring it to the foreground

14:24 then do Ctrl+C

14:24 http://www.linuxtutorialblog.com/post/tutorial-the-best-tips-tricks-for-bash

14:24 read up on process control

14:27 xicubed: thx - got it working

14:31 amalloy: opqdonut: it looks like someone wrote a library for it, at least, but amazingly i don't see it in apache commons. seems more useful than some of the crap they shove in there

14:31 http://code.google.com/p/reflectutils/source/browse/trunk/src/main/java/org/azeckoski/reflectutils/ArrayUtils.java#48

15:06 amcnamara: amalloy: ah, thanks. It seems to only bail on gzip so I removed that handler for now, I'll try building both ring and clojail sans-lein later to see if it fixes.

15:08 amalloy: amcnamara: i use cake, myself, but i know people who have used lein successfully. at least once, lein didn't work, and it exhibited this failure mode. switching to a working version of lein fixed it

15:09 coopernurse: clojurescript folks: does it offer any help in terms of DOM manipulation and event callbacks? or is that something google closure would assist with? or neither?

15:09 technomancy: amcnamara: is this about the rejected execution thing?

15:09 amcnamara: technomancy: yeah,

15:10 coopernurse: in particular I'm interested in help avoiding memory leaks resulting from orphaned DOM event listeners, etc

15:10 technomancy: amcnamara: if you make your main thread block on the server it'll work

15:10 amalloy: the issue is that gzip uses a future, which some versions of lein didn't play nice with (technomancy: accurate?)

15:10 technomancy: amalloy: it's a workaround for the fact that clojure doesn't give you any control over the thread pools it uses

15:10 amalloy: sure, i understand the cause

15:11 technomancy: http://p.hagelb.org/shutdown-agents.jpg and http://tech.puredanger.com/2010/06/08/clojure-agent-thread-pools/

15:11 having your main thread block takes care of it

15:11 clojurebot: rejectedexecutionexception?

15:11 clojurebot: RejectedExecutionException in swank means you need to upgrade swank to 1.3.2 or higher.

15:12 technomancy: hmm... not quite relevant here

15:12 amalloy: amcnamara: anyway, we also use an agent that gets updated every time someone solves a problem, so just disabling gzip wouldn't completely fix your issue

15:13 polypus74: given some java class over which i have no control, how would i go about making seq callable on instances of it. is it possible?

15:14 technomancy: amcnamara: is that something you can do?

15:15 arohner: polypus74: what clojure syntax do you want?

15:15 polypus74: (my-seq)?

15:15 amcnamara: this is running a bit over my head, but I'll spend the afternoon figuring it out :)

15:15 polypus74: arohner: (seq instance)

15:15 technomancy: polypus74: seq isn't a protocol (yet?)

15:15 so not really

15:15 polypus74: arohner: (my-seq ...) i can figure out

15:16 arohner: polypus74: since seq isn't a protocol, you have to implement ISeq

15:17 polypus74: ok ty guys

15:17 arohner: polypus74: another (crazy) option would be to make your own fork of clojure, that adds to clojure.lang.RT.seqFrom(Object)

15:17 hiredman: you can follow the lead of enumeration-seq

15:18 amalloy: and iterator-seq

15:18 arohner: yeah, that's a pretty good idea

15:18 hiredman: maybe it is interator-seq I am thinking of

15:19 polypus74: i'll have a look

15:33 gtrak`: can you do (binding ...) on a private fn var in another namespace?

15:34 amalloy: hiredman: no, i think enumeration-seq exists also

15:36 hiredman: gtrak`: yes

15:37 gtrak`: it seems to ignore me when i try

15:39 amalloy: are you trying to rebind a non-dynamic var in 1.3, then?

15:40 gtrak`: 1.2, just a (defn-

15:40 maybe I need to use var on the calling function?

15:40 to refer to the one i'm rebinding?

15:41 nope

15:43 michaelr525: heya!

15:43 r9: clojurebot: rejectedexecutionexception?

15:43 clojurebot: RejectedExecutionException in swank means you need to upgrade swank to 1.3.2 or higher.

15:43 r9: clojurebot: runtimeerror?

15:43 clojurebot: excusez-moi

16:30 sritchie: technomancy: is it okay to specify "LATEST" as the version for some dependency/

16:30 ?

16:30 I'd thought that was the case, but I'm getting a not found error, with lein

16:32 technomancy: there's a way to get the newest version; I think it's in the faq

16:32 I've never used it myself

16:36 sritchie: technomancy: looks like [0,) works, I

16:36 'll check the faq for the accepted way

16:36 Netpilgrim: sritchie: I don't know why it doesn't work with Leiningen, but you might consider using RELEASE instead of LATEST to avoid snapshots.

16:37 sritchie: Netpilgrim: yeah, this is really just for internal dev -- we've got a project with our thrift schema and generated code, so I just want to pull in anything on an update

16:37 but that's a good key to know about

17:08 jli: on line 74 of clojurescript/src/cljs/cljs/reader.cljs, should the "#" be a \#?

17:08 that is, should the "#" string be a \# character? seems like it..

17:14 oh, I guess it doesn't matter because chars become 1-character strings in javascript ?

17:15 raek: yes

17:20 gtrak`: it seems that binding is broken from run-tests on swank, yet it works in the repl, what's the dealio?

17:22 zippy314: If I have functions declared in two namespaces (i.e. in two files) that I'd like to be able to use in both namespaces, how do I declare that in the "use" declaration at the beginning of each file? I can't seem to get anything to work. It acts as though there is a strict usage hierarchy where two files can't mutually refer to each-other. Is this true?

17:24 joegallo: no circular dependencies

17:25 gtrak`: ah wait, i was just doing it wrong

17:26 amalloy: zippy314: yes, it is true

17:26 zippy314: Ouch!

17:28 Why is this? It seems like a huge limitation. Are there any workarounds?

17:29 scgilardi: search for compilation unit at: http://news.ycombinator.com/item?id=2466731

17:29 workaround is to make the hierarchy a non-cyclic graph by rearranging the contents of the namespaces

17:33 amalloy: it's a pain every so often, but most of the time if you have a problem it's because your design isn't very good - too many pieces of the design all know about each other

17:36 and the limitation exists so that clojure can compile a given form based only on forms it's already seen, rather than needing your whole program all at once. if a *correct* form could depend on code not yet read, it would mean that, for example, (defn bar [x] x) (defn foo [] (bsr baz)) couldn't be flagged as an error immediately - maybe you're planning to define bsr later

17:37 gtrak`: you can do forward declarations just like C right? can that fix cyclic dependencies?

17:38 amalloy: not between namespaces

17:53 gtrak`: what we really need is a .h file paradigm

17:53 amalloy: (defmacro pretend-this-is-C [& body] ...)

18:07 TimMc: zippy314: In my experience, it is pretty rare for a wad of code I have written to both have large-scale cyclic dependencies and also be otherwise well-structured.

18:07 I usually end up factoring out a "common" namespace.

18:07 It can happen though, I guess.

18:12 zippy314: In my case, I'm working around this by having a global registry of certain functions that I can lookup by name at runtime. The issue is that these functions are created by macros, and they represent signals that "agents" can receive. I was trying to have these "agents" (which can contain other agents) to map to clojure name-spaces. But the problem is that parent and child "agents" can send each-other signals (which are

18:41 sjl: Anyone know why an input stream defined like so: (DataInputStream. (BufferedInputStream. (.getInputStream socket))) would read data correctly when talking to a server on localhost but not read correctly when talking to a server over a network?

19:26 amcnamara: technomancy, amalloy: Got it sorted out by binding a flag to block run-jetty (using :join?) when called from -main, while keeping the run fn non-blocking by default. Thanks for the help.

21:43 solussd: leiningen question- I added ':main my.package.core' to my project.clj but 'leon repl' starts me at clojure.core. I was under the impression that :main would set my namespace in the repl

22:01 tomoj: solussd: main is, afaik, only for setting the main class in the jar manifest

22:02 solussd: ah. sad. Ideally, I'd like to build a jar that launches a repl with the namespace set to something

22:16 tomoj: hm.. you could just supply a main function that calls clojure.main/main

22:16 cemerick: solussd: Pretty easy to do.

22:16 tomoj: but that will be a crappy repl I think?

22:16 cemerick: heh, what tomoj said.

22:16 crappy?

22:16 tomoj: or is it the same as `lein repl`

22:16 never use either..

22:16 solussd: well the idea is they'd be able to kick off a handful of API tests

22:16 they don't know clojure

22:17 tomoj: putting them in a repl seem strange to me, then :)

22:17 solussd: it's a gateway drug

22:17 tomoj: I'm can't imagine getting addicted to manually balancing parentheses

22:18 solussd: most of the commands would be of the (something arg arg arg) nature

22:18 tomoj: then why not just `java -jar foo.jar something arg arg arg`? really in an effort to get them to see the light?

22:19 solussd: yeah.. really wish java didn't take so long to start up.

22:19 tomoj: ah

22:19 solussd: maybe I'll throw together a swing ui. :D

22:20 do we have a nice gui framework yet?

22:26 amalloy: lein has an option somewhere that's like "run this code every time you start a repl"

22:27 * srid wonders if developing on a hosted VM (as opposed to developing on his poor macbookair) would improve the JVM start time.

22:29 amalloy: something like :repl-options [:init (fn [] (doto 'myproj.core require in-ns))]

22:29 solussd: ^

22:31 tomoj: whoa

22:31 that looks quite useful

22:31 amalloy: tomoj: that's actually a feature of clojure.main/repl - lein just passes that option on untouched

22:32 solussd: hm.. didn't work

23:15 why would I want to use a gensym instead of ~'body and ~@'body in a macro generated by a macro?

23:20 e.g. (defmacro [blah] `(defmacro ~(symbol blah) [~'body] ~@'body)) or (defmacro [blah] `(defmacro ~(symbol blah) [body#] ~@body#))

23:24 srid: what is the equivalent of `eval-buffer` for clojure code in emacs?

23:25 I ran `m-x clojure-jack-in` to get a clojure repl going. now I want to send the entire buffer (if foo.clj) to this buffer. repeatedly (upon edits)

23:25 note that foo.clj may not be saved to disk yet

23:26 arohner: srid: C-c C-k, slime-compile-and-load-file, but that reads the file off disk

23:26 solussd: sometimes you need to use gensym to create local, unnamed variables

23:27 srid: arohner: good enough for me; i can remember to save before eval'ing.

23:27 arohner: srid: I believe it asks if you want to save

23:27 srid: yes, that's very handy!

23:29 amalloy: solussd: well, ~@'body will never do what you want in any circumstances

23:30 solussd: b/c I needed a [& ~'body] ?

23:30 amalloy: because it will try to splice in '(quote body)

23:32 solussd: hrm. ~'@body ? :D

23:32 is there any way to express this?

23:32 without a gensym

23:32 amalloy: do you have an allergy or something?

23:32 solussd: mostly just curious

23:33 and gensyms look terrible in doc strings. :D

23:33 amalloy: solussd: so set the :arglists metadata to something else

23:34 solussd: so, if I want to splice in stuff, I have to use a gensym in this case?

23:34 amalloy: i don't think it is ever the case that you *have* to use a gensym. they're just syntactic sugar for another construct

23:35 but that construct can get confusing and/or complicated

23:35 solussd: I'll buy that. Still, is there a way?

23:35 mostly b/c I want to understand it

23:35 amalloy: the quoting is complicated and i'm never quite sure

23:36 solussd: got it!

23:36 amalloy: (defmacro foo [name] `(defmacro ~name [& ~'body] `(do ~'~@body))) or something

23:36 solussd: ~@~'body

23:36 clojurebot: @ has nothing to do with whether sth is evaluated or not

23:37 srid: could someone tell me why I get "Unsupported binding" for multiple function bodies? http://dpaste.com/606442/ -- reading the defn syntax at http://clojure.org/special_forms doesn't tell me what is wrong my code.

23:37 solussd: and yes, that's ugly.

23:37 but it makes sense- I'm unquoting a quoted body and splicing it in

23:37 amalloy: srid: [nil] is wrong

23:38 srid: how would I match an empty list, then?

23:39 amalloy: clojure doesn't have pattern matching built in

23:39 srid: so it *only* does destructuring.

23:39 amalloy: yes

23:39 srid: [x & xs] works, but not, say, [2 & xs]

23:41 amalloy: yes, but see dnolen's match lib

23:42 srid: there is no if-nil? ah, anything other than nil is true

23:45 gaze__: Hey... would someone mind helping me understand how state is passed around? Let's say on the OO side I had some class (no hierarchy) that was used to represent a connection to an FTP server... it might have the host, port, username, etc. as locals, some methods that connect, set that state, list the current directory, etc.

23:45 I can recognize that you might plop all that into a record and pass it around as the first argument to all associated functions on the lisp side

23:45 but... is that the right way to do it?

23:47 in haskell I'd probably just make a state monad or something

23:49 amalloy: there are a million ways to do it. you could mimic the OO approach by having (make-connection foo) return a function for doing stuff; that function would be a closure around whatever connection-specific data you need

23:49 (defn make-connection [host] (let [connection (...open-connection)] (fn [operation] (case operation :close (.close connection)))))

23:50 srid: this is my implementation of list reverse function without using the core `reverse` - http://dpaste.com/606444/ ... can it be improved?

23:51 amalloy: srid: improved is super-vague

23:51 anyway, the answer is surely yes. try (shallow-reverse (range 100000))

23:52 srid: improved ... with respect to idiomatic clojure, and am-I-forgetting-a-core-function thing.

23:52 i couldn't use cons/conj, so had to settle for concat.

23:53 yes, it sucks at performance.

23:54 amalloy: did you try the above?

23:54 srid: does it kill my emacs proces?

23:55 ambrosebs_: has clojure.contrib.def been promoted/moved to contrib 1.3?

23:55 gaze__: okay... that kinda reminds me of something I've seen in common lisp

23:55 the sorta make-* idiom and then closing over the state

23:55 amalloy: (first (shallow-reverse (range 1e5))) if you're worried about printing too much

23:55 i strongly suspect you get a stackoverflow

23:55 gaze__: it's far from the only clojure style

23:55 but it's one that's entirely reasonable and might apply here

23:56 gaze__: what's the sort of preferred way? I don't particularly like the switching

23:56 amalloy: it depends on how much state you have, and how much you want it to change over time

23:57 srid: yes, I get stackoverflow. let me think how to fix this

23:57 gaze__: well, what are some other options?

23:58 srid: right, xs keeps accumulating over the stack in the order of N*N

23:59 gaze__: I feel like this is kinda one of the first things I wanna ask coming from an imperative background... and it's a pretty well defined thing anyway. Has anyone written anything about it?

Logging service provided by n01se.net