* 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).