Re: FileNotFoundException (Access is denied)

2009-11-26 Thread Rob Wolfe


Robert Campbell napisał(a):
 I'm trying to write a file scanner very similar to the one on page 131
 of Stuart's book:

 (ns user
   (:use [clojure.contrib.duck-streams :only [reader]]))

 (defn scan [dir]
   (for [file (file-seq dir)]
 (with-open [rdr (reader file)]
   (count (filter #(re-find #foobar %) (line-seq rdr))

 user (scan (java.io.File. C:/SomeValidDir))

 java.lang.RuntimeException: java.io.FileNotFoundException:
 C:\publishing\cosmos\trunk\web (Access is denied) (NO_SOURCE_FILE:0)

 The strange part:

 user (file-seq (java.io.File. C:/SomeValidDir))
 ( #File C:\SomeValidDir\foo1.clj #File C:\SomeValidDir\foo2.clj)
 and so on, properly listing the entire contents of the directory.

 user (for [file (file-seq (java.io.File.
 C:/publishing/cosmos/trunk/web))] nil)
 (nil nil) and so on, again working properly.

 user (for [file (file-seq (java.io.File.
 C:/publishing/cosmos/trunk/web))] (with-open [rdr (reader file)]
 nil))
 ; Evaluation aborted. (this one finally fails with the same error)

 So with-open [rdr (reader file)] is the problem, but why?

I guess reader does not work for directories. Try to change your
for loop like this:
(for [file (file-seq dir) :when (.isFile file)]

HTH,
Rob

-- 
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


Re: FileNotFoundException (Access is denied)

2009-11-26 Thread Robert Campbell
Thank you, that was the problem.

I wonder if Stuart should change this line:

(defn clojure-source? [file] (.endsWith (.toString file) .clj ))

to this:

(defn clojure-source? [file] (and (.isFile file) (.endsWith (.toString
file) .clj )))

just to make sure directories like myproj.clj don't throw an error.
I suppose that's being excessively safe for what's meant to be a
simple example.



On Thu, Nov 26, 2009 at 9:43 AM, Rob Wolfe r...@smsnet.pl wrote:


 Robert Campbell napisał(a):
 I'm trying to write a file scanner very similar to the one on page 131
 of Stuart's book:

 (ns user
   (:use [clojure.contrib.duck-streams :only [reader]]))

 (defn scan [dir]
   (for [file (file-seq dir)]
     (with-open [rdr (reader file)]
       (count (filter #(re-find #foobar %) (line-seq rdr))

 user (scan (java.io.File. C:/SomeValidDir))

 java.lang.RuntimeException: java.io.FileNotFoundException:
 C:\publishing\cosmos\trunk\web (Access is denied) (NO_SOURCE_FILE:0)

 The strange part:

 user (file-seq (java.io.File. C:/SomeValidDir))
 ( #File C:\SomeValidDir\foo1.clj #File C:\SomeValidDir\foo2.clj)
 and so on, properly listing the entire contents of the directory.

 user (for [file (file-seq (java.io.File.
 C:/publishing/cosmos/trunk/web))] nil)
 (nil nil) and so on, again working properly.

 user (for [file (file-seq (java.io.File.
 C:/publishing/cosmos/trunk/web))] (with-open [rdr (reader file)]
 nil))
 ; Evaluation aborted. (this one finally fails with the same error)

 So with-open [rdr (reader file)] is the problem, but why?

 I guess reader does not work for directories. Try to change your
 for loop like this:
 (for [file (file-seq dir) :when (.isFile file)]

 HTH,
 Rob

 --
 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

-- 
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


Atomic reloads and snapshots of namespaces

2009-11-26 Thread André Thieme
My web application needs updates from time to time.
When this happens I often have to stop the server and
shut down the JVM. Then the old (current) directories can
be replaced by the new ones, and I restart the server.

It's okay when there are several copies of the server
running behind a load balancer. This allows updates while
the service is available.

I would like to ask what other ways there are for updating
services.
One idea could be to reload a namespace?
The application could offer a way for an admin to kick of
a reload of a given namespace.

Two problems I see:
1) On the dev machine I make the changes and (compile ...)
the system. On the live machine there already exist .class
files with the same name, or at least with a very similar name.
I don't know if there could be naming conflicts, and in such a
case the OS might now allow me to overwrite a .class file, as
it is in use currently. Even if compile produces files with new
names (other number suffixes or something like that) this could
end up in a mess.

2) And even if we can manage point 1) there is still the problem
with atomicity. Or not?
I imagine a chain of n functions. Callers or callees may expect
different args. I would like to update the whole namespace as
one unit. Maybe this already works in Clojure?

One more question:
could it make sense to have a reload function which first saves
the whole namespace (by referencing all toplevel vars and
functions in that ns), then atomically reloads the namespace
from a given path on disk (containing all .class files) and finally
returns the old instances of the ns?

My idea behind this was:
when a web server starts a request then some threads could still
want to continue to execute functions of the old ns because they
did not finish their request.
Or there could be still an open session for some users which
requirs that as long this session exists these specific users are
served with the previous functions, from before the update.
This sounds a bit like making snapshots and transactions over a
namespace.

Please let me know what you think about it, if this makes sense
or would only cause too many problems, or if it won't work, etc.

-- 
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


Re: Atomic reloads and snapshots of namespaces

2009-11-26 Thread Anniepoo
I would appreciate, in a similar vein, an amplification of the Use
with caution advice in the api docs for remove-ns.  I'd like to use
remove-ns but am reluctant to architect a system around a function
marked 'use with caution'

(remove-ns sym)
Removes the namespace named by the symbol. Use with caution. Cannot be
used to remove the clojure namespace.

-- 
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


Re: Space leak with lazy sequences.

2009-11-26 Thread David Brown
On Thu, Nov 26, 2009 at 04:00:34PM -0800, David Brown wrote:

For now, I'll do without the with-open, since in this particular case,
errors are going to be fairly fatal anyway.

BTW, I still haven't been able to figure out how to write this
function without hanging onto the collection across the call to
'write-mapping'.

Any ideas?

;;
(ns leak1)
(import '[java.io FileOutputStream BufferedOutputStream DataOutputStream])

(defn make-name [ _])
(defn make-tmp-name [ _])
(defn store-properties [ _])
(defn write-mapping [ _])
(defn get-codec [ _])
(defn raise[ _])
(def error nil)

;;; The generated code creates a 'fn' class for the body of the
;;; with-open.  This class binds several of the names, including
;;; 'coll', which it keeps through the lifetime of the function.
(defn- store-index-file
   [index idx props coll]
   (let [path (make-name index idx)
 tmp-path (make-tmp-name path)
 fos (FileOutputStream. tmp-path)
 bos (BufferedOutputStream. fos)]
 (with-open [dos (DataOutputStream. bos)]
   (store-properties dos (assoc props :version 1.0))
   (write-mapping dos (get-codec index) coll)
   (.flush bos)
   ;; Calls fsync to make sure data gets written to disk.
   (.force (.getChannel fos) true))
 (when-not (.renameTo tmp-path path)
   (raise error
  (str Unable to rename pool index file: tmp-path  to  
 path)
;;

-- 
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


Re: Space leak with lazy sequences.

2009-11-26 Thread David Brown
On Thu, Nov 26, 2009 at 05:05:17PM -0800, David Brown wrote:
On Thu, Nov 26, 2009 at 04:00:34PM -0800, David Brown wrote:

For now, I'll do without the with-open, since in this particular case,
errors are going to be fairly fatal anyway.

BTW, I still haven't been able to figure out how to write this
function without hanging onto the collection across the call to
'write-mapping'.

Ugh, I have found a very ugly hack that works.

It seems that the compiler only nulls out locals before a call in the
tail position, even if earlier calls don't reference the value any
more.

So, I went down in my call-chain to the first function that uses the
sequence directly (in a doseq), and do something like this:

   (let [real-coll @coll]
 (swap! coll (constantly nil))
 (doseq [item real-coll] ...))

I just have to wrap the collection in an atom up where I create it,
and make sure I never keep a reference to it around.

David

-- 
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


Re: Atomic reloads and snapshots of namespaces

2009-11-26 Thread pmf
On Nov 26, 7:39 pm, Richard Newman holyg...@gmail.com wrote:
 Re consistency: I seem to recall Pascal Costanza working on  
 activation of layers, so you can swap a whole set of stuff across your  
 program. He spoke about it at ILC2009, but I'm not sure I've found the  
 right paper. Common Lisp-specific, though.

 He showed a website, paused mid-request, where he swapped out several  
 functions. Unpausing the request still ran to completion with the old  
 functions. A new request ran with the new functions. Impressive.

CLOS and the MOP allows you to change a class and have all already
existing instances be transformed into the new form (in an automatic
or user defined way), which makes these things much easier to achieve
than in Java- and Clojure-world.

-- 
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


Re: A Clojure Highlife

2009-11-26 Thread Chris Jenkins
Thanks for sharing this. Coincidentally, I just wrote my first Clojure
program which was... an implementation of Conway's Game of Life :-) I took a
different approach - I represented the board as a vector of vectors of
integers (1 for alive, 0 for dead) and then implemented a new-board function
that takes a board as an argument and returns the next generation of that
board. It seemed the functional way to do it. I then create an atom whose
state is a grid and repeatedly call (swap! board new-board) in order to move
it through the generations.

I'll copy the source to my little program at the bottom of this email. If
anyone has any comments on the style or possible improvements then I would
be very interested to hear them. I'm particularly keen to hear how close to
idiomatic Clojure style it is (is there a Clojure equivalent of the
adjective Pythonic?)

(import
 '(java.awt Color Graphics Dimension FlowLayout)
 '(javax.swing JPanel JFrame JButton Timer BoxLayout)
 '(java.awt.event MouseListener ActionListener ActionEvent))

(set! *warn-on-reflection* true)

(def width  50)
(def height 20)
(def cell-width 10)
(def cell-height 10)

(def sleep-time 100)

(def initial-board
; (apply vector (replicate height
; (apply vector (replicate width 0)
 [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 0 0
0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 1
1 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]])

(def board-atom (atom initial-board ))

(def running-atom (atom false))

;; Board manipulation functions

(defn print-board [b]
  (doseq [row b]
(println (str row

(defn within [v min max]
  (and (= v min) ( v max)))

(defn cell-at [b x y]
  (if (and (within x 0 width) (within y 0 height))
(nth (nth b y) x)
0))

(defn occurences [l item]
  (count (filter #(= % item) l)))

(defn new-cell-value [cell neighbours]
  (let [num-1s (occurences neighbours 1)]
(if (= cell 0)
  ; cell is currently dead and will become alive iff it has 3 living
  ; neighbours
  (if (= num-1s 3) 1 0)
  ; else cell is currently alive and will die iff it has fewer than 2 or
  ; more than 3 living neighbours
  (if (or ( num-1s 2) ( num-1s 3)) 0 1

(defn cell-neighbours [b x y]
  [(cell-at b (- x 1) (- y 1))
   (cell-at b x (- y 1))
   (cell-at b (+ x 1) (- y 1))
   (cell-at b (- x 1) y)
   (cell-at b (+ x 1) y)
   (cell-at b (- x 1) (+ y 1))
   (cell-at b x (+ y 1))
   (cell-at b (+ x 1) (+ y 1))])

(defn new-value-at [b x y]
  (let [cell (cell-at b x y)
neighbours (cell-neighbours b x y)]
(new-cell-value cell neighbours)))

(defn new-board [b]
  (vec (for [y (range height)]
(vec (for [x (range width)]
  (new-value-at b x y))

(defn flip-cell [b x y]
  (let [row  (nth b y)
cell (nth row x)
new-cell (- 1 cell)
new-row  (assoc row x new-cell)]
(assoc b y new-row)))

(defn apply-n-times [f n x]
  (if (zero? n)
x
(recur f (dec n) (f x

;; GUI functions

(defn make-action-listener [f]
  (proxy [ActionListener] [] (actionPerformed [e] (f e

(defn render [#^Graphics g b]
  (doseq [y (range height)]