<snip>
Shawn Hoover wrote:
> For example, Java doesn't have language support like C#'s using statement
> for executing some block of code and deterministically cleaning up an object
> at the end. You could implement that as a function (in many languages) and
> call it like this:
> (defn do-and-close [o f]
>   (try
>     (f)
>     (finally (.close o))))
> (let [file (FileInputStream. "todo.txt"]
>   (do-and-close file
>     (fn []
>       (do stuff with file))))
>
> In Clojure this was made cleaner with a simple macro,
> clojure.core/with-open. Usage:
> (with-open [file (FileInputStream. "todo.txt"]
>   (do stuff with file))

with-open is a good, simple macro, but with a trivial example like
that, I don't think it demonstrates well enough what macros can do for
you that functions can't. So let's make it a bit more complicated.

with-open actually supports binding *multiple* closeables that depend
on each other, just like let:

(with-open [file (FileReader. "test.file")
                   buffered (BufferedReader. file)]
 (do-stuff-with buffered))

with-open properly closes them in the reverse order, too.

compared to the function approach, which quickly gets unwieldy:
(let [file (FileReader. "test.file")]
 (do-close file (fn []
   (let [buffered (BufferedReader. file)]
     (do-close buffered (fn []
       (do-stuff-with buffered)))))

One might think that it's possible to have do-close accept multiple
files, but there's a problem:
since function arguments are evaluated when the function execution
begins, any errors happening during the creation phase will not be
caught and thus some streams might be left unclosed.

To emulate with-open perfectly, every file would have to be passed
wrapped in an anonymous function! That's a lot of boilerplate, which
would make with-open pointless, as its purpose is to eliminate
boilerplate. :)


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to