On Tue, Apr 29, 2014 at 11:25 AM, Andy Wingo <wi...@pobox.com> wrote: > Hi! > > Thanks for the feedback, it's really useful. > > On Tue 29 Apr 2014 17:56, Doug Evans <xdj...@gmail.com> writes: > >> The struct interface, contrary to what the documentation says, takes a >> stdarg list beginning with the number of fields (and not terminated >> with SCM_UNDEFINED), instead of _1, _2, _3 > > This is what the documentation says (in the info node 'Structure > Basics'): > > -- C Function: SCM scm_make_struct (SCM vtable, SCM tail_size, SCM > init_list) > -- C Function: SCM scm_c_make_struct (SCM vtable, SCM tail_size, SCM > init, ...) > -- C Function: SCM scm_c_make_structv (SCM vtable, SCM tail_size, > size_t n_inits, scm_t_bits init[]) > > I believe this to be correct.
Almost. git struct.c has: SCM scm_c_make_struct (SCM vtable, size_t n_tail, size_t n_init, scm_t_bits init, ...) >> fwiw, I would use that over the _n version. > > I thought so too and so I used this in my first attempt ;) However > scm_make_struct expects the scm_t_bits to actually be unpacked SCM > values -- which is to say, it expects them to be tagged. A bit wonky. > SCM is a perfectly valid varargs type, as evinced by scm_list_n and > friends. But that's how it is and for ABI reasons we can't really > change that. I'm not suggesting changing the API of course. :-) Plus scm_make_struct is callable from Scheme so it doesn't really support passing "uninterpretered" values (except hackily). > Then we had the points that Mark brought up about portable type-casting, > and that really we should provide separate signed/unsigned integer > interfaces and also pointer interfaces. It gets into a combinatoric > mess on the constructor level, though perhaps for N<=3 it's manageable. > Anyway then you also have to match the types that are passed as > initializers to the field type (unboxed 'u' or tagged 'p') and it's just > a big mess. I thought that the given foreign object API would cover the > majority of cases, like SMOB cases, and that for multi-field types the > ref/set accessors would be sufficient. Technically, one could provide just intptr/uintptr and skip void*, but the latter would be sufficiently convenient I think. re: The combinatoric mess, I'm not suggesting adding that. Plus, if an app wants to have an SCM in their "foreign object" they can't store it in a slot, whereas they can with structs. >> fwiw, structs already provide most of what is needed. >> I have a few gdb objects using them, and it doesn't seem too bad. > > Yes. The API doesn't support this use case so well. It also doesn't > support GOOPS method dispatch, subclassing, or named fields (unless you > start getting into records territory). IIUC, goops already had <foreign-slot>, which is what the foreign object API uses. So I still don't see what creating a whole new class of data structure provides that can't be provided by extending existing ones. And if there is something, doesn't that mean that the existing ones (goops/structs) are still broken? >> I think you should fix/extend the struct interface instead of >> inventing something new: given that structs already have >> "uninterpreted" it is most of the way there already. It's already >> intended to solve the problem you're trying to solve. >> Its API just needs a way to set/ref "uninterpreted" values directly. > > Good point. Though, it can hard to square with the existing smob/struct > cases. You could have scm_struct_unsigned_ref -- would it then untag a > 'p' value? I would flag referencing or setting a 'p' field via the "uninterpreted" accessors as errors. > It seems to me that there are some combinatorics that we do > away with by saying that "this is a foreign object. It's also a struct, > and a GOOPS instance, and you can treat it that way, but the API we > expose to C is the most useful way to treat these objects." OTOH, yet another compound data structure with its own API now exists.