# Basics

## Accessing GAP from Julia

Any global GAP variable and function can be access from Julia via the `GAP.Globals`

object; for example `GAP.Globals.Binomial(5,3)`

.

The `GAP.prompt`

command can be used to switch to a GAP session that works like a regular GAP, except that leaving it (via `quit;`

or by pressing Ctrl-D) returns one to a Julia prompt. From the GAP prompt, one can access Julia variables via the `Julia`

object, for example `Julia.binomial(5,3)`

. For more details on how to access Julia from GAP, please consult the manual of the GAP package JuliaInterface.

Alternatively, one can start GAP in the traditional way, by executing a shell script. Such a script can be created in a location of your choice via `GAP.create_gap_sh`

.

`GAP.Globals`

— Constant`Globals`

This is a global object that gives access to all global variables of the current GAP session via `getproperty`

and `setproperty!`

.

**Examples**

```
julia> GAP.Globals.Size # a global GAP function
GAP: <Attribute "Size">
julia> GAP.Globals.size # there is no GAP variable with this name
ERROR: GAP variable size not bound
[...]
julia> hasproperty( GAP.Globals, :size )
false
julia> GAP.Globals.size = 17;
julia> hasproperty( GAP.Globals, :size )
true
julia> GAP.Globals.size
17
julia> GAP.Globals.UnbindGlobal(g"size")
julia> GAP.Globals.Julia # Julia objects can be values of GAP variables
Main
```

`GAP.evalstr`

— Function`evalstr(cmd::String)`

Let GAP execute the command(s) given by `cmd`

; if an error occurs then report this error, otherwise if the last command has a result then return it, otherwise return `nothing`

.

**Examples**

```
julia> GAP.evalstr( "1+2" )
3
julia> GAP.evalstr( "x:= []" )
GAP: [ ]
julia> GAP.evalstr( "y:= 2; Add( x, 1 )" )
julia> GAP.evalstr( "x" )
GAP: [ 1 ]
```

`GAP.prompt`

— Function`prompt()`

Start a GAP prompt where you can enter GAP commands as in a regular GAP session. This prompt can be left as any GAP prompt by either entering `quit;`

or pressing ctrl-D, which returns to the Julia prompt.

This GAP prompt allows to quickly switch between writing Julia and GAP code in a session where all data is shared.

`GAP.create_gap_sh`

— Function`create_gap_sh(dstdir::String)`

Given a directory path, create three files in that directory:

- a shell script named
`gap.sh`

which acts like the`gap.sh`

shipped with a regular GAP installation, but which behind the scenes launches GAP via Julia. - two TOML files,
`Manifest.toml`

and`Project.toml`

, which are required by`gap.sh`

to function (they record the precise versions of GAP.jl and other Julia packages involved)

## Accessing Julia from GAP

The GAP-Julia interface is fully bidirectional, so it is also possible to access all Julia functionality from GAP. To learn more about this, please consult the manual of the GAP package JuliaInterface.

## Types

`GAP.FFE`

— Type`FFE`

Wrap a pointer to a GAP FFE ("finite field element") immediate object. This type is defined in the JuliaInterface C code.

**Examples**

```
julia> x = GAP.Globals.Z(3)
GAP: Z(3)
julia> typeof(x)
FFE
```

`GAP_jll.GapObj`

— Type`GapObj`

This is the Julia type of all those GAP objects that are not "immediate" (booleans, small integers, FFEs).

**Examples**

```
julia> typeof( GAP.evalstr( "[ 1, 2 ]" ) ) # a GAP list
GapObj
julia> typeof( GAP.evalstr( "rec()" ) ) # a GAP record
GapObj
julia> typeof( GAP.evalstr( "(1,2,3)" ) ) # a GAP permutation
GapObj
julia> typeof( GAP.evalstr( "2^64" ) ) # a large GAP integer
GapObj
julia> typeof( GAP.evalstr( "2^59" ) ) # a small GAP integer
Int64
julia> typeof( GAP.evalstr( "Z(2)" ) ) # a GAP FFE
FFE
julia> typeof( GAP.evalstr( "true" ) ) # a boolean
Bool
```

Note that this is Julia's viewpoint on GAP objects. From the viewpoint of GAP, also the pointers to Julia objects are implemented as "non-immediate GAP objects", but they appear as Julia objects to Julia, not "doubly wrapped".

**Examples**

```
julia> GAP.evalstr( "Julia.Base" )
Base
julia> typeof( GAP.evalstr( "Julia.Base" ) ) # native Julia object
Module
```

One can use `GapObj`

as a constructor, in order to convert Julia objects to GAP objects. Such calls are delegated to `julia_to_gap`

.

However, this is restricted to outputs that actually are of type `GapObj`

. To also deal with GAP integers, finite field elements and booleans, use `GAP.Obj`

instead.

The keyword argument `recursive`

with value `true`

can be used to force recursive conversion of nested Julia objects (arrays, tuples, dictionaries).

**Examples**

```
julia> GapObj(1//3)
GAP: 1/3
julia> GapObj([1 2; 3 4])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GAP.GapObj([[1, 2], [3, 4]])
GAP: [ <Julia: [1, 2]>, <Julia: [3, 4]> ]
julia> GAP.GapObj([[1, 2], [3, 4]], recursive = true)
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GapObj(42)
ERROR: TypeError: in typeassert, expected GapObj, got a value of type Int64
```

`GAP.Obj`

— Type`GAP.Obj`

This is an alias for `Union{GapObj,FFE,Int64,Bool}`

. This type union covers all types a "native" GAP object may have from Julia's viewpoint.

Moreover, it can be used as a constructor, in order to convert Julia objects to GAP objects, whenever a suitable conversion has been defined.

The keyword argument `recursive`

with value `true`

can be used to force recursive conversion of nested Julia objects (arrays, tuples, dictionaries).

**Examples**

```
julia> GAP.Obj(1//3)
GAP: 1/3
julia> GAP.Obj([1 2; 3 4])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GAP.Obj([[1, 2], [3, 4]])
GAP: [ <Julia: [1, 2]>, <Julia: [3, 4]> ]
julia> GAP.Obj([[1, 2], [3, 4]], recursive = true)
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GAP.Obj(42)
42
```

`GAP.GapInt`

— Type`GapInt`

Any GAP integer object is represened in Julia as either a `GapObj`

(if it is a "large" integer) or as an `Int`

(if it is a "small" integer). This type union can be used to express this conveniently, e.g. when one wants to help type stability.

Note that also GAP's `infinity`

and `-infinity`

fit under this type (as do many other objects which are not numbers).