unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* make-vtable
@ 2007-02-12 21:13 Kevin Ryde
  2007-02-13  8:13 ` make-vtable Ludovic Courtès
  0 siblings, 1 reply; 16+ messages in thread
From: Kevin Ryde @ 2007-02-12 21:13 UTC (permalink / raw)
  To: guile-devel

I made a bit of a start trying to improve the structures section of
the manual, I always found it pretty hard to follow.  One big
stumbling block for me was vtables, but I now see if you want to make
a struct you have to make a vtable vtable, and from that a vtable, and
only then your struct.  Seems hard work for casual users, if you're
not (at first) interested in that second level of "type of type".

How about something like this to just make a vtable from fields and
optional printer func,

    (define (make-vtable fields . print)
      (apply make-struct (make-vtable-vtable "" 0) 0
             (make-struct-layout fields)
             print))

I suppose a func should be judged on whether it'd be used, but a
make-vtable like this would certainly make the manual easier reading,
since you can get started making structs just from the fields layout,
and only later that learn details of sets of related types, extra
slots in the vtable(s) for class data, etc.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-12 21:13 make-vtable Kevin Ryde
@ 2007-02-13  8:13 ` Ludovic Courtès
  2007-02-13 21:26   ` make-vtable Kevin Ryde
  0 siblings, 1 reply; 16+ messages in thread
From: Ludovic Courtès @ 2007-02-13  8:13 UTC (permalink / raw)
  To: guile-devel

Hi,

Kevin Ryde <user42@zip.com.au> writes:

> I made a bit of a start trying to improve the structures section of
> the manual, I always found it pretty hard to follow.  One big
> stumbling block for me was vtables, but I now see if you want to make
> a struct you have to make a vtable vtable, and from that a vtable, and
> only then your struct.  Seems hard work for casual users, if you're
> not (at first) interested in that second level of "type of type".

My understanding (which might be inaccurate) is that there is in fact no
such three-level indirection: in classic reflective OO terms,
`make-vtable-vtable' returns a "class" object which `make-struct' can
then use to return regular (i.e., non-class) objects.  In particular,
this example (from `structs.test') works:

     (let* ((vtable (make-vtable-vtable "pr" 0))
            (s1     (make-struct vtable 0 "hello"))
            (s2     (make-struct vtable 0 "hello")))
       ;; S1 and S2 are both "regular" one-field structs.
       (equal? s1 s2))

So I think it's even more confusing than it seems.  ;-)

I'd say that `make-vtable-vtable' is inappropriately named and should
really be `make-vtable'.  Does that make sense?

(Not to mention that the primary use of the term "vtable" is for
_method_ pointers in C++, which definitely has nothing to do with this.)

> How about something like this to just make a vtable from fields and
> optional printer func,
>
>     (define (make-vtable fields . print)
>       (apply make-struct (make-vtable-vtable "" 0) 0
>              (make-struct-layout fields)
>              print))

IIUC, `(define make-vtable make-vtable-vtable)' should suffice.

Thanks,
Ludovic.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-13  8:13 ` make-vtable Ludovic Courtès
@ 2007-02-13 21:26   ` Kevin Ryde
  2007-02-14  8:01     ` make-vtable Ludovic Courtès
  0 siblings, 1 reply; 16+ messages in thread
From: Kevin Ryde @ 2007-02-13 21:26 UTC (permalink / raw)
  To: guile-devel

ludovic.courtes@laas.fr (Ludovic Courtès) writes:
>
>      (let* ((vtable (make-vtable-vtable "pr" 0))
>             (s1     (make-struct vtable 0 "hello"))
>             (s2     (make-struct vtable 0 "hello")))
>        ;; S1 and S2 are both "regular" one-field structs.

I know the "values" struct is doing exactly this, but I suspect it's
abusing the vtable system.  I suspect that what scm_init_stacks() in
stacks.c is doing is normal (if there's such a thing as "normal").

> So I think it's even more confusing than it seems.  ;-)

Yep, very confusing :-).

> I'd say that `make-vtable-vtable' is inappropriately named and should
> really be `make-vtable'.  Does that make sense?

Perhaps we have an expert lurking here, but I think make-vtable-vtable
does in fact do what its name suggests: make a vtable for creating
vtables.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-13 21:26   ` make-vtable Kevin Ryde
@ 2007-02-14  8:01     ` Ludovic Courtès
  2007-02-14 20:51       ` make-vtable Kevin Ryde
  2007-02-18 18:10       ` make-vtable Neil Jerram
  0 siblings, 2 replies; 16+ messages in thread
From: Ludovic Courtès @ 2007-02-14  8:01 UTC (permalink / raw)
  To: guile-devel

Hi,

Kevin Ryde <user42@zip.com.au> writes:

> I know the "values" struct is doing exactly this, but I suspect it's
> abusing the vtable system.  I suspect that what scm_init_stacks() in
> stacks.c is doing is normal (if there's such a thing as "normal").

I'm not sure the indirection in `scm_init_stacks ()' is needed since it
uses STACK_LAYOUT for both VTABLE and SCM_STACK_TYPE, and `make-struct'
doesn't look at the vtable's vtable anyway (when creating instances of
SCM_STACK_TYPE).

> Perhaps we have an expert lurking here, but I think make-vtable-vtable
> does in fact do what its name suggests: make a vtable for creating
> vtables.

More generally, a three-level architecture like the one you suggest
would look fishy.  For instance, GOOPS and other CLOS derivatives have
<object> and <class>, representing respectively the "base" and "meta"
levels, but they have no need for <class-class>, <class-class-class> or
some such.

Thanks,
Ludovic.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-14  8:01     ` make-vtable Ludovic Courtès
@ 2007-02-14 20:51       ` Kevin Ryde
  2007-02-15  8:45         ` make-vtable Ludovic Courtès
  2007-02-18 18:10       ` make-vtable Neil Jerram
  1 sibling, 1 reply; 16+ messages in thread
From: Kevin Ryde @ 2007-02-14 20:51 UTC (permalink / raw)
  To: guile-devel

ludovic.courtes@laas.fr (Ludovic Courtès) writes:
>
> I'm not sure the indirection in `scm_init_stacks ()' is needed since it
> uses STACK_LAYOUT for both VTABLE and SCM_STACK_TYPE,

Not sure what you mean there.

> and `make-struct'
> doesn't look at the vtable's vtable anyway (when creating instances of
> SCM_STACK_TYPE).

> More generally, a three-level architecture like the one you suggest
> would look fishy.  For instance, GOOPS and other CLOS derivatives have
> <object> and <class>, representing respectively the "base" and "meta"
> levels, but they have no need for <class-class>, <class-class-class> or
> some such.

The closest I've got to imagining it is that make-vtable-vtable
creates a root, a vtable whose parent vtable is itself.  (What I'm not
sure if it's supposed to be the root of a whole heirarchy, or just of
two levels, if you know what I mean.)

At any rate, below is where I'm up to so far with trying to make the
docs a bit easier.  It includes my proposed make-vtable.  Could be
possible to leave that out, but perhaps those like me who managed to
never understand structs can see if it makes the understanding easier
:-).



Structures
----------

A "structure" is a first class data type which holds Scheme values or C
words in slots numbered 0 upwards.  A "vtable" represents a structure
type, giving read/write permissions on slots, whether they're Scheme
values or uninterpreted words, and giving an optional print function
for the structure (for use by `write' etc).

   Structures are lower level than records (*note Records::) but have
some extra features.  The vtable system allows sets of types be
constructed, complete with per-class data.  The uninterpreted word
slots feature can be used to inter-operate with C code, so arbitrary
pointers or other values can be stored along side usual Scheme `SCM'
values.

Vtables
.......

A vtable specifies the format of a structure.  A vtable is actually
itself a structure, but there's no need to worray about that initially.
(For more details see *note Vtable Contents::.)

 -- Scheme Procedure: make-vtable fields [print]
     Create a new vtable.

     FIELDS is a string describing the slots in the structures to be
     created from this vtable.  Each slot is represented by two
     characters, a type letter and a permissions letter, for example
     `"pw"'.  The types are as follows.

        * `p' - a Scheme value.  "p" stands for "protected" meaning
          that it's protected against garbage collection.

        * `u' - an arbitrary word of data (an `scm_t_bits').  At the
          Scheme level it's read and written as an unsigned integer.
          "u" stands for "uninterpreted" (it's not treated as a Scheme
          value), or "unprotected" (it's not marked during GC), or
          "unsigned long" (its size), or all of these things.

        * `s' - a self-reference.  Such a slot holds the `SCM' value of
          the structure itself (a circular reference).  This can be
          useful in C code where you might have a pointer to the data
          array, and want to get the Scheme `SCM' handle for the
          structure.  In Scheme code it has no use.

     The second letter for each field is a permission code, as follows.

        * `w' - writable, the field can be read and written.

        * `r' - readable, the field can be read, but not written.

        * `o' - opaque, the field can be neither read nor written at the
          Scheme level.  This can be used for fields which should only
          be used from C code.

        * `W',`R',`O' - a tail array, with permissions for the array
          slots as per `w',`r',`o'.

     A tail array is further slots at the end of a structure.  The last
     field in the layout string might be for instance `pW' to have a
     tail of writable Scheme-valued slots.  The given `pW' field itself
     holds a count of the extra slots, and then those slots follow.

     Here are some examples.

          (make-vtable "pw")      ;; one writable field
          (make-vtable "prpw")    ;; one read-only and one writable
          (make-vtable "pwuwuw")  ;; one scheme and two uninterpreted

          (make-vtable "prpW")    ;; one fixed then a tail array

     The optional PRINT argument is a function called by `display' and
     `write' (etc) to give a printed representation of a structure of
     this type.  It's called `(PRINT struct port)' and should look at
     STRUCT and write to PORT.  The default print merely gives a form
     like `#<struct ADDR:ADDR>' with a pair of machine addresses.

     The following print function for example shows the two fields of
     its structure.

          (make-vtable "prpw"
                       (lambda (struct port)
                         (display "#<")
                         (display (struct-ref 0))
                         (display " and ")
                         (display (struct-ref 1))
                         (display ">")))

Structure Basics
................

This section describes the basic procedures for creating and accessing
structures.

 -- Scheme Procedure: make-struct vtable tail-size [init...]
 -- C Function: scm_make_struct (vtable, tail_size, init_list)
     Create a new structure.  VTABLE is a vtable giving the layout of
     the structure (*note Vtables::).

     TAIL-SIZE is the size of the tail array, if VTABLE specifies a
     tail array.  TAIL-SIZE should be 0 when VTABLE doesn't specify a
     tail array.

     The optional INIT... arguments are initial values for the slots of
     the structure (and the tail array).  For read-only slots this is
     the only way to set values.  If there are fewer INIT arguments
     than fields then the defaults are `#f' for a Scheme field (type
     `p') or 0 for an uninterpreted field (type `u').

     Type `s' self-reference fields and permissions `o' opaque fields
     are skipped for the INIT arguments.  An `s' is always set to the
     structure itself, and an `o' is always set to `#f' or 0 (with the
     intention that C code will use it in some way later).  The count
     field of a tail array is skipped by the INIT arguments too.

     For example,

          (define v (make-vtable "prpwpw" 0))
          (define s (make-struct v 0 123 "abc" 456))
          (struct-ref s 0) => 123
          (struct-ref s 1) => "abc"

          (define v (make-vtable "prpW" 0))
          (define s (make-struct v 2 "fixed field" 'x 'y))
          (struct-ref s 0) => "fixed field"
          (struct-ref s 1) => 2    ;; tail size
          (struct-ref s 2) => x
          (struct-ref s 3) => y

 -- Scheme Procedure: struct? obj
 -- C Function: scm_struct_p (obj)
     Return `#t' if OBJ is a structure, or `#f' if not.

 -- Scheme Procedure: struct-ref struct n
 -- C Function: scm_struct_ref (struct, n)
     Return the contents of slot number N in STRUCT.

     An error is thrown if N is out of range, or if the slot cannot be
     read because it's `o' opaque.

 -- Scheme Procedure: struct-set! struct n value
 -- C Function: scm_struct_set_x (struct, n, value)
     Set slot number N in STRUCT to VALUE.

     An error is thrown if N is out of range, or if the slot cannot be
     written because it's `r' read-only or `o' opaque.

 -- Scheme Procedure: struct-vtable struct
 -- C Function: scm_struct_vtable (struct)
     Return the vtable used by STRUCT.

     This can be used to examine the layout of an unknown structure, see
     *note Vtable Contents::.

Vtable Contents
...............

A vtable is itself a structure, it has slots which hold the slot layout
for the structures created from it, and a print function for those
structures.  The variables below allow access to those slots.

 -- Scheme Procedure: struct-vtable? obj
 -- C Function: scm_struct_vtable_p (obj)
     Return `#t' if OBJ is a vtable structure.

     Note that because vtables are simply structures with a particular
     layout, `struct-vtable?' can potentially return true on an
     application structure that happens to look like a vtable.

 -- Scheme Variable: vtable-index-layout
 -- C Macro: scm_vtable_index_layout
     The slot number of the layout specification.  The layout
     specification is a symbol like `pwpw' formed from the fields
     string passed to `make-vtable', or created by `make-struct-layout'
     (*note Vtable Vtables::).

          (define v (make-vtable "pwpw" 0))
          (struct-ref v vtable-index-layout) => pwpw

     This field is read-only, since the layout of the structures using a
     vtable cannot be changed.

 -- Scheme Variable: vtable-index-vtable
 -- C Macro: scm_vtable_index_vtable
     A self-reference to the vtable, ie. a type `s' field.  This is
     used by C code within Guile and has no use at the Scheme level.

 -- Scheme Variable: vtable-index-printer
 -- C Macro: scm_vtable_index_printer
     The slot number of the printer function.  This slot contains `#f'
     if the default print function should be used.

          (define (my-print-func struct port)
            ...)
          (define v (make-vtable "pwpw" my-print-func))
          (struct-ref v vtable-index-printer) => my-print-func

     This field is writable, so the print function can be changed
     dynamically.

 -- Scheme Procedure: struct-vtable-name vtable
 -- Scheme Procedure: set-struct-vtable-name! vtable name
 -- C Function: scm_struct_vtable_name (vtable)
 -- C Function: scm_set_struct_vtable_name_x (vtable, name)
     Get or set the name of VTABLE.  NAME is a symbol and is used in
     the default structure printing.

          (define v (make-vtable "pw"))
          (set-struct-vtable-name! v 'my-name)
          (define s (make-struct v 0))
          (display s) -| #<my-name b7ab3ae0:b7ab3730>

 -- Scheme Procedure: struct-vtable-tag handle
 -- C Function: scm_struct_vtable_tag (handle)
     Return the vtable tag of the structure HANDLE.

Vtable Vtables
..............

As noted above, vtables are structures and such a structure is itself
described by a vtable.  Such a "vtable of a vtable" can be created with
`make-vtable-vtable' below and used to build sets of related vtables,
possibly with extra application fields.

   This second level of vtable can be a little confusing.  An example,
and indeed a typical use, is Guile's own record system (*note
Records::).  Currently record types are implemented as vtables, and
those vtables have an extra slot holding the list of field names for
that type (as passed to `make-record-type').

 -- Scheme Procedure: make-vtable-vtable user-fields tail-size [print]
 -- C Function: scm_make_vtable_vtable (user_fields, tail_size,
          print_and_init_list)
     Create a "vtable-vtable" which can be used to create vtables.  This
     vtable-vtable is also a vtable, and is self-describing, meaning its
     vtable is itself.  The following is a simple usage.

          (define vt-vt (make-vtable-vtable "" 0))
          (define vt    (make-struct vt-vt 0
                                     (make-struct-layout "pwpw"))
          (define s     (make-struct vt 0 123 456))

          (struct-ref s 0) => 123

     `make-struct' creates a vtable from the vtable-vtable.  The first
     initializer is a layout object (slot `vtable-index-layout').  The
     `make-struct-layout' function (below) can create this from a
     string description.  An optional second initializer to
     `make-struct' is a printer function (slot `vtable-index-printer'),
     used as described under `make-vtable' (*note Vtables::).


     USER-FIELDS is a layout string giving extra slots to have in the
     vtables.  A vtable starts with some base fields (as per *note
     Vtable Contents::), and USER-FIELDS is appended.  The USER-FIELDS
     slots start at `vtable-offset-user' (below), and exist in both the
     vtable-vtable and in the vtables created from it.  Such fields
     provide space for "class data".  For example,

          (define vt-of-vt (make-vtable-vtable "pw" 0))
          (define vt       (make-struct vt-of-vt 0))
          (struct-set! vt vtable-offset-user "my class data")

     TAIL-SIZE is the size of the tail array in the vtable-vtable
     itself, if USER-FIELDS specifies a tail array.  This can be zero
     if nothing extra is required or the format has no tail array.  The
     tail array slot such as `pW' holds the tail array size, as usual,
     and is followed by the extra space.

          (define vt-vt (make-vtable-vtable "pW" 20))
          (define my-vt-tail-start (1+ vtable-offset-user))
          (struct-set! vt-vt (+ 3 my-vt-tail-start) "data in tail")

     The optional PRINT argument is used by `display' and `write' (etc)
     to print the vtable-vtable and any vtables created from it.  It's
     called as `(PRINT vtable port)' and should look at VTABLE and
     write to PORT.  The default is the usual structure print function,
     which gives just `#<struct ...>'.

 -- Scheme Procedure: make-struct-layout fields
 -- C Function: scm_make_struct_layout (fields)
     FIELDS is a string such as `"pwpw"' describing structure fields.
     Check the format is valid and convert it to a symbol, ready for
     use in vtable creation.  See `make-vtable' (*note Vtables::) for
     the format of FIELDS.

          (make-struct-layout "prpW") => prpW
          (make-struct-layout "blah") => ERROR

 -- Scheme Variable: vtable-offset-user
 -- C Macro: scm_vtable_offset_user
     The first slot in a vtable which is available for application use.
     Such slots only exist when specified by USER-FIELDS in
     `make-vtable-vtable' above.

   Here's an extended vtable-vtable example, creating classes of
"balls".  Each class has a "colour", which is fixed; instances of balls
are created and each has an "owner", which can be changed.

     (define ball-root (make-vtable-vtable "pr" 0))

     (define (make-ball-type ball-color)
       (make-struct ball-root 0
     	       (make-struct-layout "pw")
                    (lambda (ball port)
                      (format port "#<a ~A ball owned by ~A>"
                              (color ball)
                              (owner ball)))
                    ball-color))
     (define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user))
     (define (owner ball) (struct-ref ball 0))

     (define red (make-ball-type 'red))
     (define green (make-ball-type 'green))

     (define (make-ball type owner) (make-struct type 0 owner))

     (define ball (make-ball green 'Nisse))
     ball => #<a green ball owned by Nisse>



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-14 20:51       ` make-vtable Kevin Ryde
@ 2007-02-15  8:45         ` Ludovic Courtès
  2007-02-16  0:07           ` make-vtable Kevin Ryde
  0 siblings, 1 reply; 16+ messages in thread
From: Ludovic Courtès @ 2007-02-15  8:45 UTC (permalink / raw)
  To: guile-devel

Hi,

Kevin Ryde <user42@zip.com.au> writes:

> ludovic.courtes@laas.fr (Ludovic Courtès) writes:
>>
>> I'm not sure the indirection in `scm_init_stacks ()' is needed since it
>> uses STACK_LAYOUT for both VTABLE and SCM_STACK_TYPE,
>
> Not sure what you mean there.

We have:

  VTABLE -> SCM_STACK_TYPE -> stack objects

where `x -> y' means "`y' is an instance of `x'".  When creating stack
objects with (roughly) `(make-struct stack-type)', VTABLE is _not_
consulted at all.  The layout of stack objects is determined only by
that specified in SCM_STACK_TYPE.  Thus, VTABLE is redundant.

All this would be clearer if we had a `struct-vtable' type such that
`(make-struct struct-vtable)' would yield a new vtable (just like `(make
<class>)' yields a new GOOPS class).  Like `<class>', `struct-vtable'
would terminate the "reflective tower" (i.e., its vtable is itself).

Actually, such a `struct-vtable' stealthily appears in
`make-vtable-vtable', under the name of REQUIRED_VTABLE_FIELDS: We could
really have a `struct-vtable' whose layout is REQUIRED_VTABLE_FIELDS and
then `make(-vtable)+' could be simply implemented in terms of
`make-struct' (just like `make-class' uses `make').

I guess I should try implementing this theory one of these days.  ;-)

> At any rate, below is where I'm up to so far with trying to make the
> docs a bit easier.  It includes my proposed make-vtable.  Could be
> possible to leave that out, but perhaps those like me who managed to
> never understand structs can see if it makes the understanding easier
> :-).

Thanks for working on this!

> A "structure" is a first class data type which holds Scheme values or C
> words in slots numbered 0 upwards.  A "vtable" represents a structure
> type, giving read/write permissions on slots, whether they're Scheme
> values or uninterpreted words, and giving an optional print function
> for the structure (for use by `write' etc).

Perhaps a word saying the struct fields are laid out in a contiguous
memory area, which makes interaction with C much easier (using C arrays
or some such).

> Vtable Vtables
> ..............
>
> As noted above, vtables are structures and such a structure is itself
> described by a vtable.  Such a "vtable of a vtable" can be created with
> `make-vtable-vtable' below and used to build sets of related vtables,
> possibly with extra application fields.
>
>    This second level of vtable can be a little confusing.  An example,
> and indeed a typical use, is Guile's own record system (*note
> Records::).  Currently record types are implemented as vtables, and
> those vtables have an extra slot holding the list of field names for
> that type (as passed to `make-record-type').

While the rest looks good, I remain skeptical about this part.  And a
manual that claims to be confusing does not inspire confidence.  ;-)

Thanks,
Ludovic.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-15  8:45         ` make-vtable Ludovic Courtès
@ 2007-02-16  0:07           ` Kevin Ryde
  2007-02-16  8:12             ` make-vtable Ludovic Courtès
  0 siblings, 1 reply; 16+ messages in thread
From: Kevin Ryde @ 2007-02-16  0:07 UTC (permalink / raw)
  To: guile-devel

ludovic.courtes@laas.fr (Ludovic Courtès) writes:
>
> When creating stack
> objects with (roughly) `(make-struct stack-type)', VTABLE is _not_
> consulted at all.  The layout of stack objects is determined only by
> that specified in SCM_STACK_TYPE.

Yes.

> Thus, VTABLE is redundant.

Well, except for the creation (and continued existance) of
scm_stack_type.

> All this would be clearer if we had a `struct-vtable' type such that
> `(make-struct struct-vtable)' would yield a new vtable (just like `(make
> <class>)' yields a new GOOPS class).  Like `<class>', `struct-vtable'
> would terminate the "reflective tower" (i.e., its vtable is itself).

Yes, as long as you don't want any extra fields in the vtable (which
is true for scm_stack_type).  I thought of that for my make-vtable
func,

    (define make-vtable
      (let ((vtable-vtable #f))
        (lambda (fields tail-size . print)
          (or vtable-vtable
              (set! vtable-vtable (make-vtable-vtable "" 0)))
          (apply make-struct vtable-vtable tail-size
                 (make-struct-layout fields)
                 print))))

Then wondered if it was worth bothering with.  I guess if it's used by
stacks.c too then it should share.  (The name `struct-vtable' is taken
by a func, but some other global name ...)

> Actually, such a `struct-vtable' stealthily appears in
> `make-vtable-vtable', under the name of REQUIRED_VTABLE_FIELDS: We could
> really have a `struct-vtable' whose layout is REQUIRED_VTABLE_FIELDS and
> then `make(-vtable)+' could be simply implemented in terms of
> `make-struct' (just like `make-class' uses `make').

I think the problem is if you want extra fields in the vtables.  Maybe
a third level of table descriptor could do that (as opposed to
self-vtabling roots).  Though for now I'm only really looking at
describing it, not changing it.

> Perhaps a word saying the struct fields are laid out in a contiguous
> memory area, which makes interaction with C much easier (using C arrays
> or some such).

Yep.  I guess documenting SCM_STRUCT_DATA or whatever it is to get at
them will be necessary too, if we're really pretending it's useful in
C.

> While the rest looks good, I remain skeptical about this part.  And a
> manual that claims to be confusing does not inspire confidence.  ;-)

It's ok to admit it's potentially confusing, if that's then followed
by good explanation :-).


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-16  0:07           ` make-vtable Kevin Ryde
@ 2007-02-16  8:12             ` Ludovic Courtès
  0 siblings, 0 replies; 16+ messages in thread
From: Ludovic Courtès @ 2007-02-16  8:12 UTC (permalink / raw)
  To: guile-devel

Hi!

Kevin Ryde <user42@zip.com.au> writes:

>> Thus, VTABLE is redundant.
>
> Well, except for the creation (and continued existance) of
> scm_stack_type.

Right.  But the layout that's used for VTABLE is unneeded: VTABLE only
needs REQUIRED_VTABLE_FIELDS.

> Yes, as long as you don't want any extra fields in the vtable (which
> is true for scm_stack_type).  I thought of that for my make-vtable
> func,
>
>     (define make-vtable
>       (let ((vtable-vtable #f))
>         (lambda (fields tail-size . print)
>           (or vtable-vtable
>               (set! vtable-vtable (make-vtable-vtable "" 0)))
>           (apply make-struct vtable-vtable tail-size
>                  (make-struct-layout fields)
>                  print))))
>
> Then wondered if it was worth bothering with.  I guess if it's used by
> stacks.c too then it should share.  (The name `struct-vtable' is taken
> by a func, but some other global name ...)

I think it'd be useful and easier to understand.  Or maybe something
like:

  (define %root-vtable
    (make-vtable-vtable "" 0))

  (define (make-vtable layout printer)
    ;; LAYOUT must be a symbol.  We only pass a two-element init list
    ;; (corresponding to REQUIRED_VTABLE_FIELDS) because the second
    ;; field is of type `s' and gets automatically initialized.
    (make-struct %root-vtable 0 layout printer))

(And it really works!)

Both of which could (should?) be documented _before_ `make-vtable-vtable'
is even mentioned.  :-)

> I think the problem is if you want extra fields in the vtables.

Actually, one rarely needs it, just like one rarely needs to sub-class
<class>.  So it's a nice thing to have, but not something that should
make one's life harder.

> Maybe
> a third level of table descriptor could do that (as opposed to
> self-vtabling roots).

Because of the `s' field in REQUIRED_VTABLE_FIELDS, all vtables returned
by `make-vtable-vtable' are "self-vtabling".  I think it'd be clearer if
there were only one self-vtabling vtable (`%root-vtable') from which all
vtables would directly or indirectly inherit.  Thus,
REQUIRED_VTABLE_FIELDS would rather be "prprpw".

But I guess this is more of a cosmetic issue.

Thanks,
Ludo'.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-14  8:01     ` make-vtable Ludovic Courtès
  2007-02-14 20:51       ` make-vtable Kevin Ryde
@ 2007-02-18 18:10       ` Neil Jerram
  2007-02-18 20:05         ` make-vtable Ludovic Courtès
  1 sibling, 1 reply; 16+ messages in thread
From: Neil Jerram @ 2007-02-18 18:10 UTC (permalink / raw)
  To: guile-devel

ludovic.courtes@laas.fr (Ludovic Courtès) writes:

> More generally, a three-level architecture like the one you suggest
> would look fishy.  For instance, GOOPS and other CLOS derivatives have
> <object> and <class>, representing respectively the "base" and "meta"
> levels, but they have no need for <class-class>, <class-class-class> or
> some such.

Actually, a lot of the GOOPS doc finds it useful to talk in terms of
three levels: object, class, and metaclass.

Also, in practice, I've done a fair amount of programming using GOOPS,
and have found metaclass-level customization extremely useful.

I think Kevin's new doc is great.

Regards,
     Neil



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-18 18:10       ` make-vtable Neil Jerram
@ 2007-02-18 20:05         ` Ludovic Courtès
  2007-02-18 23:56           ` make-vtable Neil Jerram
  0 siblings, 1 reply; 16+ messages in thread
From: Ludovic Courtès @ 2007-02-18 20:05 UTC (permalink / raw)
  To: guile-devel

Hi,

Neil Jerram <neil@ossau.uklinux.net> writes:

> ludovic.courtes@laas.fr (Ludovic Courtès) writes:
>
>> More generally, a three-level architecture like the one you suggest
>> would look fishy.  For instance, GOOPS and other CLOS derivatives have
>> <object> and <class>, representing respectively the "base" and "meta"
>> levels, but they have no need for <class-class>, <class-class-class> or
>> some such.
>
> Actually, a lot of the GOOPS doc finds it useful to talk in terms of
> three levels: object, class, and metaclass.

Right, but a "metaclass" is the class of class, i.e., a class (IOW, a
metaclass is an instance of <class> or a sub-class thereof).  So that's
really two levels.

> Also, in practice, I've done a fair amount of programming using GOOPS,
> and have found metaclass-level customization extremely useful.

I didn't mean to say it's not useful, just that it's maybe not something
one wants to know when reading about structs for the first time.

Thanks,
Ludovic.



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-18 20:05         ` make-vtable Ludovic Courtès
@ 2007-02-18 23:56           ` Neil Jerram
  2007-02-19  0:14             ` make-vtable Kevin Ryde
  0 siblings, 1 reply; 16+ messages in thread
From: Neil Jerram @ 2007-02-18 23:56 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

ludo@chbouib.org (Ludovic Courtès) writes:

> Right, but a "metaclass" is the class of class, i.e., a class (IOW, a
> metaclass is an instance of <class> or a sub-class thereof).  So that's
> really two levels.

That's true, but then it's also true that a class is an instance - so
you could say that's just one level.

In other words, this isn't clear cut.  We're into matters of opinion
here, on what kind of terminology and description is most useful to
someone learning.

>> Also, in practice, I've done a fair amount of programming using GOOPS,
>> and have found metaclass-level customization extremely useful.
>
> I didn't mean to say it's not useful, just that it's maybe not something
> one wants to know when reading about structs for the first time.

That's a fair point, but IMO Kevin's doc layout allows for it by
putting the vtable-vtable stuff last.

Regards,
     Neil



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-18 23:56           ` make-vtable Neil Jerram
@ 2007-02-19  0:14             ` Kevin Ryde
  2007-02-19  0:39               ` make-vtable Neil Jerram
  2007-02-19  8:39               ` make-vtable Ludovic Courtès
  0 siblings, 2 replies; 16+ messages in thread
From: Kevin Ryde @ 2007-02-19  0:14 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-devel, Ludovic Courtès

Neil Jerram <neil@ossau.uklinux.net> writes:
>
> That's a fair point, but IMO Kevin's doc layout allows for it by
> putting the vtable-vtable stuff last.

It's last because it's the most brain twisting :).

Is the "ball" example your code?  It looks fairly typical (a "colour"
field in the vtable which is a constant), if the few words introducing
it give the right sense of what it's meant to be about.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-19  0:14             ` make-vtable Kevin Ryde
@ 2007-02-19  0:39               ` Neil Jerram
  2007-02-19  8:39               ` make-vtable Ludovic Courtès
  1 sibling, 0 replies; 16+ messages in thread
From: Neil Jerram @ 2007-02-19  0:39 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

Kevin Ryde <user42@zip.com.au> writes:

> Is the "ball" example your code?  It looks fairly typical (a "colour"
> field in the vtable which is a constant), if the few words introducing
> it give the right sense of what it's meant to be about.

No, not mine.  I didn't recall seeing it before, so I assumed you had
invented it.  I think it's a good example, anyway.

Regards,
     Neil



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-19  0:14             ` make-vtable Kevin Ryde
  2007-02-19  0:39               ` make-vtable Neil Jerram
@ 2007-02-19  8:39               ` Ludovic Courtès
  2007-03-06  0:27                 ` make-vtable Kevin Ryde
  1 sibling, 1 reply; 16+ messages in thread
From: Ludovic Courtès @ 2007-02-19  8:39 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-devel

Hi,

Kevin Ryde <user42@zip.com.au> writes:

> Neil Jerram <neil@ossau.uklinux.net> writes:
>>
>> That's a fair point, but IMO Kevin's doc layout allows for it by
>> putting the vtable-vtable stuff last.
>
> It's last because it's the most brain twisting :).

I think it's the right term.  ;-)

I agree with putting the vtable-vtable stuff last, and I think Neil is
right in saying that all this is a matter or terminology and taste.

> Is the "ball" example your code?  It looks fairly typical (a "colour"
> field in the vtable which is a constant), if the few words introducing
> it give the right sense of what it's meant to be about.

I'd have assumed this was Tom Lord's but I don't have any evidence.

Thanks,
Ludovic.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-02-19  8:39               ` make-vtable Ludovic Courtès
@ 2007-03-06  0:27                 ` Kevin Ryde
  2007-03-06  8:32                   ` make-vtable Ludovic Courtès
  0 siblings, 1 reply; 16+ messages in thread
From: Kevin Ryde @ 2007-03-06  0:27 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 181 bytes --]

I'm looking at the code below for my new `make-vtable'.  I'm still not
completely convinced it's a great idea, but it does at least find a
use in stacks.c, so it can't be all bad!


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: struct.c.vtable.diff --]
[-- Type: text/x-diff, Size: 1718 bytes --]

--- struct.c.~1.111.2.6.~	2007-03-06 11:19:49.000000000 +1100
+++ struct.c	2007-03-06 11:20:55.000000000 +1100
@@ -560,6 +560,28 @@
 #undef FUNC_NAME
 
 
+static SCM scm_i_vtable_vtable_no_extra_fields;
+
+SCM_DEFINE (scm_make_vtable, "make-vtable", 1, 1, 0,
+            (SCM fields, SCM printer),
+	    "Create a vtable, for creating structures with the given\n"
+	    "@var{fields}.\n"
+	    "\n"
+	    "The optional @var{printer} argument is a function to be called\n"
+	    "@code{(@var{printer} struct port)} on the structures created.\n"
+	    "It should look at @var{struct} and write to @var{port}.")
+#define FUNC_NAME s_scm_struct_vtable_tag
+{
+  if (SCM_UNBNDP (printer))
+    printer = SCM_BOOL_F;
+
+  return scm_make_struct (scm_i_vtable_vtable_no_extra_fields, SCM_INUM0,
+                          scm_list_2 (scm_make_struct_layout (fields),
+                                      printer));
+}
+#undef FUNC_NAME
+
+
 /* Return true if S1 and S2 are equal structures, i.e., if their vtable and
    contents are the same.  Field protections are honored.  Thus, it is an
    error to test the equality of structures that contain opaque fields.  */
@@ -879,6 +901,11 @@
     = scm_permanent_object (scm_make_weak_key_hash_table (scm_from_int (31)));
   required_vtable_fields = scm_from_locale_string ("prsrpw");
   scm_permanent_object (required_vtable_fields);
+
+  scm_i_vtable_vtable_no_extra_fields =
+    scm_permanent_object
+    (scm_make_vtable_vtable (scm_nullstr, SCM_INUM0, SCM_EOL));
+
   scm_c_define ("vtable-index-layout", scm_from_int (scm_vtable_index_layout));
   scm_c_define ("vtable-index-vtable", scm_from_int (scm_vtable_index_vtable));
   scm_c_define ("vtable-index-printer",

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: stacks.c.vtable.diff --]
[-- Type: text/x-diff, Size: 1101 bytes --]

--- stacks.c.~1.83.2.1.~	2006-02-14 08:59:02.000000000 +1100
+++ stacks.c	2007-03-06 11:21:05.000000000 +1100
@@ -1,5 +1,5 @@
 /* Representation of stack frame debug information
- * Copyright (C) 1996,1997,2000,2001, 2006 Free Software Foundation
+ * Copyright (C) 1996,1997,2000,2001, 2006, 2007 Free Software Foundation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -740,14 +740,10 @@
 void
 scm_init_stacks ()
 {
-  SCM vtable;
-  SCM stack_layout
-    = scm_make_struct_layout (scm_from_locale_string (SCM_STACK_LAYOUT));
-  vtable = scm_make_vtable_vtable (scm_nullstr, SCM_INUM0, SCM_EOL);
-  scm_stack_type
-    = scm_permanent_object (scm_make_struct (vtable, SCM_INUM0,
-					     scm_cons (stack_layout,
-						       SCM_EOL)));
+  scm_stack_type =
+    scm_permanent_object
+    (scm_make_vtable (scm_from_locale_string (SCM_STACK_LAYOUT),
+                      SCM_UNDEFINED));
   scm_set_struct_vtable_name_x (scm_stack_type,
 				scm_from_locale_symbol ("stack"));
 #include "libguile/stacks.x"

[-- Attachment #4: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: make-vtable
  2007-03-06  0:27                 ` make-vtable Kevin Ryde
@ 2007-03-06  8:32                   ` Ludovic Courtès
  0 siblings, 0 replies; 16+ messages in thread
From: Ludovic Courtès @ 2007-03-06  8:32 UTC (permalink / raw)
  To: guile-devel

Hi,

Kevin Ryde <user42@zip.com.au> writes:

> I'm looking at the code below for my new `make-vtable'.  I'm still not
> completely convinced it's a great idea, but it does at least find a
> use in stacks.c, so it can't be all bad!

I find it nice and useful, so I'm all in favor of adding it, along with
the documentation you wrote.

Thanks!

Ludo'.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2007-03-06  8:32 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-12 21:13 make-vtable Kevin Ryde
2007-02-13  8:13 ` make-vtable Ludovic Courtès
2007-02-13 21:26   ` make-vtable Kevin Ryde
2007-02-14  8:01     ` make-vtable Ludovic Courtès
2007-02-14 20:51       ` make-vtable Kevin Ryde
2007-02-15  8:45         ` make-vtable Ludovic Courtès
2007-02-16  0:07           ` make-vtable Kevin Ryde
2007-02-16  8:12             ` make-vtable Ludovic Courtès
2007-02-18 18:10       ` make-vtable Neil Jerram
2007-02-18 20:05         ` make-vtable Ludovic Courtès
2007-02-18 23:56           ` make-vtable Neil Jerram
2007-02-19  0:14             ` make-vtable Kevin Ryde
2007-02-19  0:39               ` make-vtable Neil Jerram
2007-02-19  8:39               ` make-vtable Ludovic Courtès
2007-03-06  0:27                 ` make-vtable Kevin Ryde
2007-03-06  8:32                   ` make-vtable Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).