Hi, SMOBs have a few problems. 1) They are limited in number to 255. 2) It's difficult to refer to a SMOB type from Scheme. You can use class-of once you have an object, but the class-of isn't exactly the same as the SMOB tc16, and getting the type beforehand is gnarly. (See http://article.gmane.org/gmane.comp.gdb.patches/96857 for an example). 3) You can't create SMOB types from Scheme. This goes against our general trend of making Scheme more powerful. 4) You can't create SMOB objects from Scheme. 5) Similarly, you can't access SMOB fields from Scheme. 6) You can't subclass SMOB types. (Some people would like this ability.) 7) There is legacy code out there that uses e.g. SCM_SETCDR to set smob fields. (This is terrible, but it exists: https://github.com/search?q=SCM_SETCDR+smob&ref=cmdform&type=Code for an example.) 8) The single/double SMOB thing is outdated and bogus. Objects should be able to have any number of fields. 9) We document mark functions in the manual, even recommending them, but they are really difficult to get right (see https://lists.gnu.org/archive/html/guile-user/2011-11/msg00069.html), and almost always a bad design -- the BDW GC can do a better job without them. And yet, if we consider the generic problem of wrapping C objects in Scheme objects, it's clear that we have more solutions now than we used to -- raw # values, define-wrapped-pointer-type, etc. But there's nothing that's accessible to C like SMOBs are, so people that use the libguile interface to wrap C types and values are out of luck. I propose to provide a new interface that will eventually make SMOBs obsolete. This new interface is based on structs with raw fields -- the 'u' fields. (See http://www.gnu.org/software/guile/docs/master/guile.html/Vtables.html#Vtables for description of 'u' fields. Note that the documentation is wrong -- these fields are indeed traced by the GC.) Here is the proposed C API: SCM scm_make_foreign_object_type (SCM name, SCM slot_names, scm_t_struct_finalize finalizer); void scm_assert_foreign_object_type (SCM type, SCM val); SCM scm_make_foreign_object_1 (SCM type, scm_t_bits val0); SCM scm_make_foreign_object_2 (SCM type, scm_t_bits val0, scm_t_bits val1); SCM scm_make_foreign_object_3 (SCM type, scm_t_bits val0, scm_t_bits val1, scm_t_bits val2); SCM scm_make_foreign_object_n (SCM type, size_t n, scm_t_bits vals[]); scm_t_bits scm_foreign_object_ref (SCM obj, size_t n); void scm_foreign_object_set_x (SCM obj, size_t n, scm_t_bits val); The finalizer may be NULL. The scm_make_foreign_object* functions are just scm_make_struct without the no_tail arguments, and interpreting the values as raw untagged values, not unpacked SCM values. Same thing with scm_foreign_object_ref/set_x. The overhead of a foreign object is two words -- the same as the overhead on any struct. (Compare to SMOBs, which have a half-word overhead.) Here is the proposed Scheme API: ;; Exported from (system foreign-object): (define* (make-foreign-object-type name slots #:key finalizer) ...) (define-syntax-rule (define-foreign-object-type name constructor (slot ...) kwarg ...) (begin (define name (make-foreign-object-type 'name '(slot ...) kwarg ...)) (define slot [getter for slot]) ... (define constructor (lambda (slot ...) [...])))) Foreign object types are GOOPS classes, although this is not really exposed in the API. Foreign objects are GOOPS objects -- with no additional overhead of course, compared to structs. You can subclass an object type; see the test-foreign-object-scm test in the patch below. So, what do people think? The patch below is against stable-2.0. Andy