This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: Simple example program to illustrate Goops
- To: le_douanier at yahoo dot com
- Subject: Re: Simple example program to illustrate Goops
- From: Neil Jerram <neil at ossau dot uklinux dot net>
- Date: Fri, 28 Jan 2000 23:02:47 GMT
- CC: guile at sourceware dot cygnus dot com
- References: <20000128181502.11380.qmail@web1806.mail.yahoo.com>
Julien Rousseau writes:
--- Neil Jerram <neil@ossau.uklinux.net> wrote:
> Does this help you at all?
Yes and no.
Yes because it illustrate well what is described in
the tutorial and in a compact manner, but also no
because what I am looking for is more a "small"
software that would explain its use in a bigger scale.
When I first came to Guile I used Gnu Robots as a
starting point to understand Guile's interaction with
C. This is this kind of program I am looking for.
Right. You would like to see a whole program written using GOOPS, to
get a better idea of how an object-oriented style program in Guile
fits together.
What would help me would be a list of free software
project using or experimenting Goops so I can see if
one of them fits my criteria, a little bit like what
we can find for guile-gtk at
http://www.ping.de/sites/zagadka/guile-gtk/apps.html
Well you're definitely asking in the best possible place, but it may
be that such a program does not yet exist, since GOOPS is still a
relatively new addition to Guile.
And another thought (enter vague, handwaving mode)... I have a
feeling that it is easier and more natural in Scheme than in other
languages to mix OO and non-OO styles. Even when you do find a
substantial program that uses GOOPS, it may not necessarily follow
that the program uses GOOPS in all its parts, or even has an OO style
throughout.
"It's undocumented"
Ok, let me comment it to see if I have understood
goops correctly.
Thank you for the compliment! All of your comments are correct --- do
you mind if I keep them in my source code? --- except for three
corrections/clarifications:
1. It is possible for (db-file-name db) to be non-#f and (db-port db)
#f if the file named in db-open doesn't yet exist. The named file
will be created the first time that db-sync or db-close is called.
2. mkpath is like mkdir, except that it creates all the required
intervening directories:
;; mkpath PATH
;;
;; Create the sequence of directories required for the pathname PATH.
;; The component of PATH after the last forward slash is interpreted
;; as a file name, not as a directory path component. This makes it
;; convenient to call mkpath with the full file name of a file that
;; you are about to create, as a way of ensuring that the containing
;; directories exist.
(define (mkpath path)
(let* ((slash (string-rindex path #\/))
(dir (and slash
(> slash 0)
(make-shared-substring path 0 slash))))
(cond
((not dir) ;; Nothing to do.
)
((and (file-exists? dir)
(not (file-is-directory? dir)))
(error "Path includes an existing file name!"))
((file-exists? dir) ;; Nothing to do.
)
(else
(mkpath dir)
(mkdir dir)))))
3. The term "generic method" is incorrect. A "generic function" is a
collection of "methods" (or sometimes "generic function methods"). A
generic function is what you apply to a set of arguments in the code.
Application of a generic function considers the types of the
arguments, and the methods that belong to the generic function, and
works out which of the methods should be applied to those arguments.
Now one or two questions:
-I assume that assoc-set! first do assoc on the
association list (db-cache db) using the key and then
sets its cdr (that is the value fo the association
pair) the its third argument. I also assume that when
their is no such association pair it creates one, but
does it create the pair in a sorted way (using the key
to sort the association list). I suppose so but givne
that you use map in db-close (see next question) I
wonder.
(set! (db-cache db)
(assoc-set! (db-cache db) key value))
I believe that all your assumptions are correct. My application that
uses this simple database doesn't need the keys to be sorted. ...
-Shouldn't the map of db-close be a for-each, given
that R5RS specify
"The dynamic order in which proc is applied to the
elements of the lists is unspecified."
or is the possibility to have key-value pairs written
in any order not a problem?
... And I only used map in db-close because I didn't know about
for-each at the time! for-each would indeed be clearer here, since I
am interested in side effects, not in the mapped values.
-Why are the functions defined with define-method, I
understand that it is useful for
overloading functions but in this case I don't see the
use (or maybe the usefulness of it is seen
in another part of the software).
Taking this code on its own, there is no benefit in using generic
functions. But a very common idea with databases is to have several
different database implementations that all support the same
interface. So that's what I had in mind. (In fact, the application
which uses this code also uses another db implementation, which maps a
single database with hierarchical keys into a hierarchically arranged
set of <db-scm-alist> databases with simpler keys. If you're
interested, this other implementation is at
http://www.ossau.uklinux.net/hierarchical.scm.)
(For completeness w.r.t. databases, I should say that there are already
several proper database implementations for Guile - see Greg Harvey's
projects page, and that there was discussion on the list a few months
ago about implementing a generic database interface with multiple
implementations along the lines of Perl's DBI. My stuff is very basic
compared to those.)
Regards,
Neil