This page is part of the web mail archives of SRFI 50 from before July 7th, 2015. The new archives for SRFI 50 contain all messages, not just those from before July 7th, 2015.
Hi! As the document correctly points out, calls from Scheme to C can be a lot more efficient, if it is known that callbacks into Scheme do not occur. This applies to Chicken (for example), where all sorts of weird thingshappen in such a case. So, here I'm down on my knees, *begging* for separate
forms of Scheme->C calls that forbid callbacks. This also simplifies the case when threads are involved (if thread-switches can only occur in Schemecode). Note that Scheme->C calls outnumber Scheme->C->Scheme ones usually by
a large amount. It's absolutely unnecessary to specify which C-level forms are macros, or which are functions. Leave that to the implementors, and allow all the forms to be macros instead. Whether SCHEME_EXPORT_FUNCTION expandsinto "scheme_define_exported_binding" or into something different is relatively
unimportant. Moreover, it might be helpful to change the referencesof "scheme_define_exported_binding" and "scheme_enter_pointer" to uppercase, since obviously the macro-versions are meant here. Look how the (case- dependent) distinction between functions and macros already produced some confusion! ;-)
Defining bindings from C is allowed, and the SRFI-document specifically points out the C init-code may run before Scheme init-code. Yet,SCHEME_DEFINE_EXPORTED_BINDING may GC, even before Scheme init-code has run?
Weird. Or does "Scheme initialization code" not include the basic setup of the Scheme system - if not, please state so explicitly. I find it a bit tricky to exactly specify what may GC and what not. For example: mutations (a la "SCHEME_RECORD_SET") may very well allocatestorage (if the write-barrier involves allocating something on the heap, that describes the mutated slot). The life-time of data on the heap may be extremely short - what happens if GC or finalizers run in a different
OS-level thread?The authors would do good by not assuming every Scheme implementation does it like S48 or PLT.
Alternative approaches would be: 1) Selectively switch GC on/off in sections of C code (just like critical sections, really). 2) Allocate *once* a complete chunk that will be able to hold all data needed subsequently without triggering a GC. Numeric types: complex numbers are not required by R5RS. I would propose making accessors and constructors for extended number types optional.SCHEME_CALL: "For example, suppose Scheme procedure s0 captures continuation a and then calls C procedure c0, which in turn calls Scheme procedure s1. Procedure s1 can safely call the continuation a, because that is a downward use. When a is called Scheme will remove the portion of the C stack used by the call to c0."
How do you know that? Why do you specify this? Does this mean a is a special kind of continuation, one that uses longjmp()? What if continuations are explicit
(in a CPS manner)?"On the other hand, if s1 captures a continuation, that continuation cannot be used from s0, because by the time control returns to s0 the C stack used by c0 will no longer be valid. An attempt to invoke an upward continuation that is closed over a portion of the C stack will raise an exception."
Why should it raise an exception? We are interfacing Scheme with C, so probably
speed is the matter. Since C is an unsafe language, I propose to remove all superfluous safety-checks. If I want to write safe code, I use Scheme. The lack of specification about how exactly foreign code is brought into the Scheme system is understandable but unfortunate. Although this might be material for a future SRFI, I would recommend to put a little bit more thought into this. I consider an FFI SRFI like this one extremely important, since it may well be the first step towards a platform-and implementation-independent library of useful code for Scheme, so I acknowledge the effort put into SRFI-50 by the authors. Unfortunately it appears to me that this is just a polishedup version of the S48 FFI, dragging in a lot of unnecessary (and implementation-
dependent) details which may or may not fit other implementations.Why have countless macros that access and create Scheme data? Some basic forms
for defining code callable from Scheme (and vice versa) would be more than enough, together with a simple system of specifying Scheme->C->Scheme type mappings. This would also remove the GC-related problems (mostly).There are many different strategies of implementing a Scheme memory- management- and execution model, so it would be much more worthwhile (and in the end also more efficient) to provide a simplified method of simply running chunks of C code:
Scheme data -> C code -> Result value(s). That's it.Wait, it could be made even more interesting: specify a mapping of Scheme types to abstract foreign types, then add type-mappings for different languages (C, Java, etc.), and a simple interface for invoking blocks of foreign code and returning from it...