Index: list, Directory Example
First, we have a brief aside from our main topic.
The following is a convenient abbreviation:
(list 1 3 5 7) = (cons 1 (cons 3 (cons 5 (cons 7 empty))))Using list introduces the exact same cons structure, but it is easier for humans to read in big or nested lists, as in some data structures we're now using. When writing programs on lists, you should still think in terms of the cons structure.
In short, cons and empty are the constructors of lists. list is another function which makes lists, and is convenient shorthand for combinations of the constructors.
The following are data definitions for for a simplified representation of files and directories, as seen in class:
A file is a symbol (its name). A directory is a structure (make-dir name contents) where name is a symbol, and contents is a l-o-f-d. A list-of-files-and-directories (l-o-f-d) is one of - empty - (cons f lofd) where f is a file, and lofd is a l-o-f-d - (cons d lofd) where d is a directory, and lofd is a l-o-f-d.Observe the mutual recursion between directories and list-of-files-and-directories.
Also, as seen in class, the following are the corresponding templates:
;(define (dir-fn a-dir) ; ...(dir-name a-dir)... ; ...(lofd-fn (dir-contents a-dir))...) ;(define (lofd-fn a-lofd) ; (cond ; [(empty? a-lofd) ; ...] ; [(file? (first a-lofd)) ; ...(first a-lofd)...(lofd-fn (rest a-lofd))...] ; [(dir? (first a-lofd)) ; ...(dir-fn (first a-lofd))...(lofd-fn (rest a-lofd))...]))
To do:
Develop a function
; find? : directory file -> boolean ; returns whether the given file is in the directory or one ; of its subdirectories
Note that this is a vast simplification of find, the mother-of-all UNIX directory traversing commands.
Develop a function
; flatten-dir : directory symbol -> (directory or l-o-f-d) ; Returns a structure like the original directory, except that the ; named directory is removed, with its contents moved up one level.Here are a couple pictorial examples, in both cases removing the directory named to-remove.
Input | Output | |
---|---|---|
Example 1: |
foo / | \ bar baz to-remove / \ one two |
foo / / \ \ bar baz one two |
Example 2: |
to-remove / | \ foo bar baz |
foo bar baz |
Follow the templates and think about a single case at a time. If you do that, it shouldn't be too difficult. If you don't, you'll probably have real trouble.
For the curious... Give more accurate data definitions for modeling UNIX directories and files. Files have not only names, but contents and other properties, such as an owner and last-modified date. A directory is considered to be a kind of file.
Here are solutions.