[GAP] GAP Kernel API (known to some as libgap)

Markus Pfeiffer markus.pfeiffer at st-andrews.ac.uk
Mon Aug 27 11:46:11 BST 2018


Dear all,

in the last couple of years we have made some progress towards 
providing GAP as a dynamically loadable library; To some extent 
this comes as a side effect of kernel cleanup, while we had 
requests (mainly from SageMath, but more recently also the OSCAR 
project) to provide a way to use GAP inside other programs.

When used as a DLL, the GAP kernel can be used in ways it was not 
intended to be; GAP would (in the past) rightfully assume its in 
control of its own process.
Some kernel functions are not documented at all, and could make 
any kind of assumptions or have any kind of effect, and can 
currently be called by any "client" messing up GAP's internal 
state.

My most recent attempt to work towards "GAP as a library" is here

    https://github.com/gap-system/gap/pull/2702

together with some discussion which has unfortunately been hidden 
by how github handles comments. This is one of the reasons why I 
decided to pull this issue into the mailing list.

The above pull request is almost the "bare bones" of "GAP as a 
library".

There are the following big construction sites when it comes to 
GAP as a library.

It is probably more productive to address them separately; they 
have independent benefits to GAP, and are largely independent of 
each other. 

  * Input and Output

    As a library GAP cannot assume to be in control of a terminal 
    receiving input, and printing output.

    Refactoring in the scanner (reading string input and passing 
    it to the reader) makes it easier to read code from streams 
    and interpret it. This work is far from complete; it is still 
    not possible to have an alternative read-evaluate-print loop 
    in GAP or to make syntax highlighting tools using the GAP 
    scanner/reader.

    Some refactoring of the output code is underway; we can 
    capture GAP's output and not just print it to stdout, but 
    there is still a lot of work to do. 

    Some relevant work in progress open pull requests are 

     https://github.com/gap-system/gap/pull/1815
     https://github.com/gap-system/gap/pull/1816
     https://github.com/gap-system/gap/pull/1817
     
  * Memory management 
 
    GAP has to co-exist (and even cooperate) with external memory 
    managers. Sage is just using GASMAN with a callback to mark 
    bags they want to keep alive, whereas OSCAR integrates GAP 
    entirely with Julia's memory manager.  We also have support 
    for the Boehm garbage collector stemming from HPC-GAP.
 
  * Signal handling

    If used as a DLL, GAP cannot assume that it is in control of 
    signal handling. The current approach (used by SageMath) is to 
    just disable all signal handling in GAP with a patch; this of 
    course doesn't keep the IO package from trying to install 
    signal handlers (and sometimes it might be necessary to handle 
    signals in some way, even when used as a library).

  * Error handling 
 
    What happens if an error occurs while evaluating some command 
    or executing some GAP functions? What state is GAP left in? We 
    can't just enter a break loop, but we should also not just 
    leave GAP in an inconsistent state. 
 
    This area has caused some grief very recently, most noably 
    documented in issue #2487 
 
     https://github.com/gap-system/gap/issues/2487 
 
    It seems that a plan how to handle errors in GAP needs to be 
    established in terms of what do we expect to happen when an 
    error occurs? How is an error condition signaled to the 
    "outside world" of GAP? Should we provide some structured 
    error object? A traceback?

  * API 

    To address the issue of "anyone could call any function at any 
    time", I first thought it would be a great idea to have a 
    well-defined API for the GAP kernel.

    I made multiple attempts to make one but alas the 
    "stakeholders" of the GAP library API (SageMath and OSCAR) 
    would really like an API, (or they don't want an API and are 
    just happy calling into GAP in whichever way), but don't give 
    feedback.
    I am personally not using such an API, even though I can 
    imagine use-cases; it seems that an API that naturally 
    develops with demand is preferable in terms of 
    time-efficiency.

    Maybe everyone will just develop their own layer of code to 
    call into GAP. [1]

    Max Horn recently suggested to just declare some existing 
    functions "official":

      https://github.com/gap-system/gap/pull/2702#discussion_r212797897

    Declaring functions official is of course akin to defining an 
    API: we'll have to document what they do, and can't easily 
    change their behaviour in case someone relies on it.

    Arguably GAP kernel extensions already rely on us not changing 
    functions (because we'd break these kernel modules), though I 
    see GAP kernel extensions more as an "internal" bit of code, 
    not an outside use of GAP as a library.

Without usecases (for me) PR 2702 will be the last thing I do on 
providing GAP as a library. 

Cheers,
Markus

[1] Which will of course have its own problems because we might rename
    GAP kernel functions, remove them, change what they do. But that is then
    not our problem anymore.
    


More information about the Gap mailing list