unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Chris Vine <vine35792468@gmail.com>
To: guile-user@gnu.org
Subject: Re: Difficulty integrating with Swift/Objective-C
Date: Mon, 6 Sep 2021 17:28:44 +0100	[thread overview]
Message-ID: <20210906172844.ed1fd1affdd8c64e73069705@gmail.com> (raw)
In-Reply-To: <m2k0jum236.fsf@inktvis.org>

On Mon, 06 Sep 2021 20:26:53 +1000
paul <paul@inktvis.org> wrote:
> Hey Chris,
> 
> On 2021-09-05 at 20:56 AEST, quoth Chris Vine 
> <vine35792468@gmail.com>:
> > 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:
> > https://sourceforge.net/p/cxx-gtk-utils/git/ci/master/tree/c++-gtk-utils/extension.h
> >
> > 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.

Chris



  reply	other threads:[~2021-09-06 16:28 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-05  6:03 Difficulty integrating with Swift/Objective-C paul
2021-09-05  8:26 ` Taylan Kammer
2021-09-05  9:35   ` paul
2021-09-06 10:21   ` paul
2021-09-06 13:11     ` Taylan Kammer
2021-09-05 10:56 ` Chris Vine
2021-09-06 10:26   ` paul
2021-09-06 16:28     ` Chris Vine [this message]
2021-09-08 23:59 ` paul
2021-09-28 20:22   ` Aleix Conchillo Flaqué

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210906172844.ed1fd1affdd8c64e73069705@gmail.com \
    --to=vine35792468@gmail.com \
    --cc=guile-user@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).