[capi-sig] Python to Scheme type conversion in C?

Jason Baker amnorvend at gmail.com
Mon May 31 22:31:23 CEST 2010


On Mon, May 31, 2010 at 3:06 PM, Stefan Behnel <stefan_ml at behnel.de> wrote:
> [please always reply to the list]

Sorry.  :-/

> Jason Baker, 31.05.2010 21:45:
>>
>> On Mon, May 31, 2010 at 2:05 PM, Stefan Behnel wrote:
>>>
>>> Jason Baker, 31.05.2010 18:15:
>>>>
>>>> I'm working on a Python-to-mzscheme binding using mzscheme's ffi
>>>> library (mzscheme's rough equivalent of the Python ctypes library).
>
> Since you didn't provide the link (and "mzscheme ffi" doesn't get me
> anything that looks right at first sight), am I right in guessing that you
> might be referring to this?
>
> http://download.plt-scheme.org/doc/351/html/foreign/

That's an older version of the docs, but yes.  Here's a more recent
link:  http://docs.plt-scheme.org/foreign/index.html

>>>> I'm looking for a way to convert Python objects into Scheme values.
>>>> Essentially what I'm trying to do is say "Is this a Python  integer?
>>>> Ok, convert it to a Scheme integer."  or "Is this a Python string?
>>>> Ok, convert it into a Scheme string."  ... etc.
>>>>
>>>> What is the best way to do this?  My first intuition was to call
>>>> Py*_Check to determine the type, but it turns out that's a macro that
>>>> can't be used in non-c code.  I'm sure I could translate that into the
>>>> appropriate C code, but that gives me a bad feeling.
>>>
>>> Those are macros because that makes them really, really fast, especially
>>> in
>>> Py3. However, their definition changes between Python versions, so
>>> replacing
>>> them by regular C code is really not a good idea.
>>>
>>> In general, I wouldn't try to make the wrapper too generic. You might
>>> want
>>> to inspect the underlying Scheme code (potentially at runtime), and infer
>>> the possible types (or the required conversion) from that.
>>
>> Perhaps I should clarify. For now, I'm just trying to embed the python
>> interpreter in Scheme.  Thus, I know what types the scheme values are,
>> and I know how to translate them into the appropriate Python values.
>> What I'm trying to figure out is how to go the other way.  That is,
>> how do I figure out what type a PyObject is so I know how to create
>> the appropriate Scheme value?
>
> Why not write a type checking cascade in plain C or Cython?

I suppose I could, but I'd rather write it in pure Scheme or Python if
at all possible.  If that's not efficient enough, I can look into
adding C into the mix.

>>>> Right now, I'm
>>>> looking for simple and easy more than efficient and complete (but I
>>>> would also like to know what the efficient and complete approach would
>>>> be).
>>>
>>> Have you considered integrating this with Cython via a thin C bridge,
>>> instead of talking to Python's C-API directly? Without knowing anything
>>> about the FFI you are using here, I suspect that it likely wouldn't be a
>>> generic wrapper in that case. Instead, it would allow users to write
>>> specialised and well optimised Scheme wrappers for their specific use
>>> case.
>>> So far, Cython supports calling into C, C++ and Fortran, where the
>>> Fortran
>>> wrapper is also implemented as a C-bridge (via fwrap). A similar Scheme
>>> binding would allow users to take advantage of Cython's static typing
>>> features, so that your code wouldn't have to guess types in the first
>>> place.
>>
>> While I'm sure this approach works for C, C++, and Fortran, I'm afraid
>> I don't see how this would apply to Scheme.  Scheme is a dynamically
>> typed language just like Python.  Why do I want a layer of static
>> typing in between two dynamically typed languages?
>
> Scheme is a strictly typed language, though, and your Scheme code won't run
> with (or even accept) arbitrary Python input value types, just like your
> Python code won't run with arbitrary Scheme value types as input. So you
> have to draw the line somewhere. And since you are using an FFI, which, I
> assume, passes through C anyway, you might just as well restrict your glue
> code to suitable types.

I suppose I could use tagged pointers[1], but I was wanting something
more generic (in other words, an interface that automatically does the
right thing).  Perhaps I'm biting off more than I can chew though.

[1]  http://docs.plt-scheme.org/foreign/Derived_Utilities.html#(part._foreign~3atagged-pointers)


More information about the capi-sig mailing list