This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Simple example program to illustrate Goops


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]