Accueil Blog Contact
fil RSSAbonnez-vous via RSS

Entrées récentes

Archives

Higher Order Programming in Scheme

I have been reading "Higher Order Perl Programming" lately. One of the example of using higher order functions is a file system traversing. Given a directory as a starting point you call a user specified function for each of the files in the directory. In case you encounter a directory then do the same for all of its files and so on.

Here is the Scheme version of this functions:

(define (for-each-file path proc)
  (cond 
   ((file-directory? path)
    (let ((names (directory-files path)))
      (for-each (lambda (p)
		  (if (or (string=? p ".") (string=? p ".."))
		      'do-nothing
		      (let ((complete-path (string-append (file-name-as-directory path)
							  "/"
							  p)))
			(for-each-file complete-path proc))))
		names)))
   (else (proc path))))

Then you can use it to display the list of HTML files in a given directoy with:

(for-each-file "." (lambda (f) (if (string=? ".html" (file-name-extension f))
				   (display f))))

Note that you may find all the Texinfo (filenames with extension ".texi") files in a directory with:

(for-each-file "." (lambda (f) (if (string=? ".texi" (file-name-extension f))
				   (display f))))

Note that you may do the same for all the Scheme or Perl or whatever file kind in a given directory. Is there not a pattern here ? Of course, you can come up with the following function:

(define (find-files-with-extension path extension)
  (for-each-file path (lambda (f) (if (string=? extension (file-name-extension f))
				      (display f)))))

Now you can simply call the function and pass it the desired file extension. Our examples now becomes:

(find-files-with-extension "." ".html")
(find-files-with-extension "." ".texi")
(find-files-with-extension "." ".scm")
(find-files-with-extension "." ".pl")

Let's go a bit further. What happens if you want to name such functions. Something like:

(define (find-html-files path) (find-files-with-extension path ".html"))
(define (find-texinfo-files path) (find-files-with-extension path ".texi"))
(define (find-scheme-files path) (find-files-with-extension path ".scm"))

You can achieve the same result with a higher order procedure. Why don't we construct a builder function: give it an extension and it gives you a procedure for find all files having this extension in a directory.

(define (make-file-finder-with-extension extension)
  (lambda (path) (find-files-with-extension path extension)))

Now our specific procedures find-html-files, find-textinfo-files, find-scheme-files may be written like that:

(define find-html-files (make-file-finder-with-extension ".html"))
(define find-texinfo-files (make-file-finder-with-extension ".texi"))
(define find-scheme-files (make-file-finder-with-extension ".scm"))

Just give me an extension and I give you a functions for finding all files in a directory having this precise extension. Give me X and I give you a function that Y. Isn't it nice ?

Commentaires

Ajouter un commentaire

Nom: requis
URL: (optionel)
Mail: requis (mais ne sera jamais affiché en public)
13+4= basic human verification