[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Difficulty integrating with Swift/Objective-C

From: Chris Vine
Subject: Re: Difficulty integrating with Swift/Objective-C
Date: Mon, 6 Sep 2021 17:28:44 +0100

On Mon, 06 Sep 2021 20:26:53 +1000
paul <> wrote:
> Hey Chris,
> On 2021-09-05 at 20:56 AEST, quoth Chris Vine 
> <>:
> > You appear to want to run scheme code as an extension language, 
> > via the
> > guile VM, in a program written for MacOS in the Swift language.
> This is exactly right.
> > I know
> > nothing about the Swift language and whether it has a sufficient 
> > C-like
> > FFI to achieve this, but you may get some inspiration from the
> > following, which enables scheme code to be run as an extension 
> > language
> > within a C++ program:
> >
> >
> > However there are various issues.  First, guile's exceptions
> > (based on C's longjmp()/setjmp() and cognates) are almost 
> > certainly
> > not implemented in the same way as Swift's exceptions (assuming 
> > Swift
> > has exceptions), which means amongst other things that, if Swift 
> > has
> > something akin to destructors/deinitialization, you should not 
> > allow
> > guile exceptions to leave Swift objects undestroyed were guile 
> > to
> > jump out of local scope on raising an exception 
> > (scm_dynwind_begin(),
> > scm_dynwind_end and scm_dynwind_unwind_handler can be useful 
> > here if
> > you are able to manage your Swift objects manually in C).  Nor 
> > more
> > generally should you allow Swift exceptions (if Swift has them) 
> > to
> > escape out of a guile scm_dynwind_begin()/scm_dynwind_end() 
> > pair, or
> > you will stop guile's resource management working correctly.
> >
> > Secondly, there are some issues relating to the fact that 
> > guile's
> > 'make-fresh-user-module' and 'load' procedures leak memory, 
> > which can
> > be problematic if all tasks run as scheme code are not to share 
> > the
> > same top level.
> >
> > Thirdly you will need to cater for translating guile return 
> > values such
> > as lists or vectors into containers that Swift can work with, 
> > and vice
> > versa.
> >
> > This is all pretty well documented in the C++ code mentioned 
> > above, but
> > it is not for the faint hearted.
> I'll definitely take a look at the codebase you link; thank you. 
> Although i am probably on the fainter-hearted side, i have a bit 
> of hope it might be feasible, since my project actually already 
> includes a "core" implemented in Rust and included as a 
> statically-linked library.  I'm able to call out to Rust functions 
> i've marked as `extern C`, and so while i don't fully understand 
> the mechanism and the implications for threading and exceptions, 
> so far it has worked well in that limited case.  I'm hoping that i 
> can make something similar work in Guile.  I think my needs are 
> fairly modest - initially my ambition is to allow the user to 
> rebind shortcut keys of my app using a Guile script.  We'll see 
> what else i can come up with later.
> Thanks for the info though, i'll definitely refer back if i run 
> into issues!

If you cut the code that I referred to down to its bare essentials, it
does what I think you have now arrived at yourself: calling
scm_eval_string() (in that code's case, actually
scm_eval_string_in_module()), via scm_with_guile().  It is
scm_with_guile() which actuates the guile VM within your program and
under which your scheme code is evaluated.  You don't need to (and
really shouldn't) execute another main() procedure within your program
to evaluate the scheme code, and doing that would make integrating it
with your Swift code much more difficult.

scm_with_guile() and scm_eval_string() will execute guile code within
your program as if it were any other C function.  However the
complications arise when you try to interface the scheme value returned
by scm_eval_string (and so by scm_with_guile()) into your Swift code -
that is, convert SCM values to Swift values, or you need to deal with
guile or Swift exceptions.  Obviously the first of those is less
relevant if you are only executing scheme code for its side effects.
There are also important issues to be aware of if you intend to execute
guile code in more than one thread or you don't want every task called
up by scm_with_guile() to share the same top level.  Looking at the code
I posted should be useful for dealing with those issues.

But the essentials of what you are doing seems right.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]