Closed Bob131 closed 3 years ago
An option that's possibly simpler (and cleaner) than number one above would be to provide some API for mapping Scheme values to the GIBaseInfo
from which they were derived. A module could then wrap guile-gi, defining a new load
method which did the same transformation(s) that would have been done in a load_infos()
hook. The mapping might be trickier to implement for some types than others, but at least for the method case gig_function_define1()
could instantiate a subclass of <method>
containing a function-info
field.
Hmm. I'd have to give it some thought.
Do you really need to modify load_infos()
directly? Guile-GI allows you to load merely parts of a given library into your own module, so you could for instance load all GTask
-related functions and then define an 8sync-style wrapper in the same module.
Most functions in GLib-based libraries ending with _async
and _finish
are implemented using GTask
. These are the functions needing wrapping. I guess one could just load every typelib on the system and use module reflection to do the wrapping, but it doesn't strike me as being terribly practical (although maybe I should try it)
I don't think, this should be terribly difficult using FP. For instance, assuming _async
and _finish
to just be thunks for simplicity, you could
(define (async->sync _async _finish)
(lambda ()
(_async)
(_finish)))
Now, for the actual implementation of whatever you're trying to do, (_async . args)
will produce a GAsyncResult
, that you can then pass to _finish
. It may also happen, that you need to pass the first argument (the "this
" pointer) to both of them. With a structure similar to this, you could e.g. launch the _async
like that and then delay
the _finish
, producing a Scheme-style promise you can force
.
As I said above, I've already thought about how this could be implemented. Whilst I appreciate your effort, your advice on the topic is not helpful: it's not particularly relevant to the immediate issue (using introspection to wrap asyncs rather than having to manually wrap all relevant functions from any GLib-based library that uses them), and if you actually read any of the relevant documentation you'd find that the GLib async APIs (or, in fact, any async APIs with which I'm familiar) don't work in the way you've assumed (and if they did, your suggestion would be pretty obvious).
I apologise for and genuinely regret my rudeness here, but I feel I must be frank: I'm not interested in having an endless circular discussion about how I've so clearly misunderstood every facet of the topic under consideration with someone who, from my perspective at least, doesn't appear to have taken the time themselves to try and understand the issue raised. If the miscommunication along these lines is to continue, I'd rather the bug was closed WONTFIX.
That escalated quickly. Closed, without prejudice. Feel free to open a new issue in future if you want to discuss the issue further.
Having quite enjoyed making use of 8sync's nonblocking I/O facilities (see the preface to 8sync's manual, particularly the points on delimited continuations and nonblocking I/O), I'd really like to see some supporting infrastructure for this style in guile-gi to simplify code making use of GLib's
GTask
andGMainLoop
APIs.However, it's unclear to me exactly how much of this should live in guile-gi itself. I have a couple of ideas (in my guess of ascending order of burden on guile-gi):
guile-gi could expose some hooks in
load_infos()
for arbitrarily transforming SCM values before they're defined, and punt the rest off to a third-party module. This has the benefit of being quite flexible, possibly enabling/simplifying more third-party features, but it seems pretty hairy (for instance, what happens if more than one transformer hook is registered?)guile-gi could use an approach analogous to
(ice-9 suspendable-ports)
: use the heuristics employed by other bindings to identify async methods (see this discussion for more) and expose parameters similar towait-for-readable-port
andwait-for-writable-port
to be called when async methods are invoked, again punting implementation to a third-party module. This doesn't get us all the way there (doesn't cover async IO onGIOChannel
s done with watches, main loop timeouts,GSource
s in general) but would cover most GIO-based APIs.Implement everything in gi-guile itself, so
(use-typelib ...)
automatically produces 8sync-style automatic async modules. I have some thoughts on how this could be done, working around issues of non-suspendable continuations due to recursion through C, but I suspect they're likely to be controversial ;)