[plt-scheme] Linking Scheme- and C-variables
On Saturday, November 1, 2003, at 11:57 AM, Daniel K. Skovenborg wrote:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
>> I access c-doubles, for example, by making a
>> closure-like primitive for
>> each variable:
>>
>> scheme_add_global( "access-the-double",
>> scheme_make_closed_prim_w_arity(
>> AccessADouble,
>> &theDouble,
>> "access-the-double",
>> 0, 1), e);
>>
>> AccessADouble is written to return theDouble with
>> scheme_make_double(theDouble). If a parameter is
>> supplied, it is
>> validated then stored in theDouble first.
>>
>> Ie, (access-the-double 12.3) "sets" theDouble to
>> 12.3.
>> (access-the-double) "gets" 12.3 .
>
> That's exactly what I'm trying to avoid: making access-functions for
> each variable that should be used :)
AccessADouble is only written once, and can be bound to as many
variables as you care to register with scheme_make_closed_prim_w_arity.
To handle groups of values, I have also written primitives that map
scheme lists to c-arrays. Mapping lists to C++ properties might be
more suitable for your purpose.
>
> But now that access-functions is the only way to do it, what do people
> here thinks of the following solutions I thought of (please note that
> it's a game I'm making, so be performance-minded):
>
> 1. The variables are stored in C, so to speak, and all variables are
> registered in a std::map <std::string, T*> (yes, I use C++. Please
> don't kill me ;)) where T* is a pointer to the type (so there's one
> map for each type used).
>
> We can now make an access-function for each type instead of each
> variable.
That's what the closure primitive provides. And you can "do-tricks" by
passing a structure pointer to the primitive. Members of the structure
can contain instructions for the primitive, even if the primitive only
returns a value from the structure.
>
> So to access the integer foo we use
> (get-int "foo")
> which will look for the key "foo" in the map containg pointers to
> the
> integers and return the value of the integer pointed to by the item
> with the key "foo". And similar we can set foo to 42 with
> (set-int "foo" 42)
> and the use the hack posted by Eli Barzilay while I was writing
> this mail.
>
> The stupid thing about this method, I guess, is that the map should
> be managed the whole time (when making/deleting variables).
>
> 2. The variables are in the Scheme environment and can be accessed in
> similar ways:
> SCHEME_INT_VAL( scheme_evaluate_string("foo", env) ) to get the
> value of the integer foo. To set the variable:
> Scheme_Object * args[2] = {scheme_evaluate_string("foo", env),
> scheme_make_integer(42)};
> scheme_apply(set, 2, args);
> where
> Scheme_Object * set = scheme_evaluate_string("set!", env);
>
> This could either be encapsulated in C-functions (taking a string
> argument that contains the name of the variable) or in a class (one
> for each type) with overloaded 'type'-operator (for example operator
> int for the integer-wrapper class) and = operator. I like the latter
> best.
>
> So what do the gurus here think?
>
>> I veered away from the set! route since I don't like the idea of
>> parallel universes of variables when the two languages are so
>> different. What happens if a c-double shadows a scheme variable that
>> is set with (sqrt -1) ?
>
> Mmh, yes, I'll have to watch my step.