Kaappi Extensions¶
Kaappi-specific features not part of R7RS or standard SRFIs.
FFI (Foreign Function Interface)¶
ffi-open¶
Syntax: (ffi-open path)
Opens a shared library (.so on Linux, .dylib on macOS) and returns a
library handle. The path is a string specifying the library file.
The handle is used with ffi-fn to bind C functions and must be closed
with ffi-close when no longer needed.
ffi-fn¶
Syntax: (ffi-fn lib "c-name" '(param-types ...) 'return-type)
Binds a C function from the shared library lib and returns a callable
Scheme procedure. The c-name is a string naming the C function.
Parameter and return types are specified as symbols: int, long,
double, float, string, pointer, void, bool, uint8, int8,
int16, int32, int64, uint16, uint32, uint64, size_t, char.
kaappi> (define lib (ffi-open "libm.so"))
kaappi> (define c-sqrt (ffi-fn lib "sqrt" '(double) 'double))
kaappi> (c-sqrt 16.0)
;=> 4.0
kaappi> (define c-pow (ffi-fn lib "pow" '(double double) 'double))
kaappi> (c-pow 2.0 10.0)
;=> 1024.0
Note
Type annotations must match the C function signature exactly. Passing a mismatched type causes undefined behavior.
ffi-close¶
Syntax: (ffi-close lib)
Closes the shared library handle lib, releasing the associated
resources. Any procedures previously bound with ffi-fn from this
library become invalid and must not be called after closing.
Green Threads (Fibers)¶
spawn¶
Syntax: (spawn thunk)
Creates and immediately starts a new fiber that executes thunk (a
procedure of zero arguments). Fibers are cooperatively scheduled green
threads that run on the VM's event loop. Returns a fiber object that can
be passed to fiber-join to retrieve the result.
kaappi> (define f (spawn (lambda () (* 6 7))))
kaappi> (fiber-join f)
;=> 42
kaappi> (define f2 (spawn (lambda ()
(display "fiber running\n")
'done)))
fiber running
kaappi> (fiber-join f2)
;=> done
See also: fiber-join, yield,
thread-start! (OS thread equivalent)
yield¶
Syntax: (yield)
Voluntarily gives up the current fiber's time slice, allowing the
scheduler to run other ready fibers. Returns an unspecified value.
Since fibers are cooperatively scheduled, long-running computations
should call yield periodically to avoid starving other fibers.
kaappi> (spawn (lambda ()
(let loop ((i 0))
(when (< i 5)
(display i) (display " ")
(yield)
(loop (+ i 1))))))
;=> #<fiber>
kaappi> 0 1 2 3 4
See also: spawn,
thread-yield! (OS thread equivalent)
fiber?¶
Syntax: (fiber? obj)
Returns #t if obj is a fiber, #f otherwise.
kaappi> (fiber? (spawn (lambda () 42)))
;=> #t
kaappi> (fiber? (current-thread))
;=> #f
kaappi> (fiber? 'not-a-fiber)
;=> #f
See also: spawn
fiber-join¶
Syntax: (fiber-join fiber)
Blocks until fiber completes and returns its result value. If the
fiber raised an exception, fiber-join re-raises it in the calling
context.
kaappi> (define f (spawn (lambda () (+ 10 20))))
kaappi> (fiber-join f)
;=> 30
kaappi> (define f2 (spawn (lambda ()
(let loop ((i 0) (acc 0))
(if (= i 100)
acc
(begin (yield) (loop (+ i 1) (+ acc i))))))))
kaappi> (fiber-join f2)
;=> 4950
See also: spawn,
thread-join! (OS thread equivalent)
Channels¶
make-channel¶
Syntax: (make-channel)
Creates a new synchronous channel for inter-fiber communication. Channels are Go-style: a send blocks until a receiver is ready, and a receive blocks until a value is available. This provides a safe way to pass data between fibers without shared mutable state.
See also: channel-send,
channel-receive, channel?
channel-send¶
Syntax: (channel-send channel value)
Sends value on channel. If no fiber is currently waiting to receive, the sending fiber blocks until a receiver is ready. This ensures synchronous hand-off of values between fibers.
kaappi> (define ch (make-channel))
kaappi> (spawn (lambda () (channel-send ch 42)))
;=> #<fiber>
kaappi> (channel-receive ch)
;=> 42
See also: channel-receive,
make-channel
channel-receive¶
Syntax: (channel-receive channel)
Receives a value from channel. If no value is currently available, the receiving fiber blocks until a sender provides one. Returns the sent value.
kaappi> (define ch (make-channel))
kaappi> (spawn (lambda ()
(channel-send ch 'hello)
(channel-send ch 'world)))
;=> #<fiber>
kaappi> (channel-receive ch)
;=> hello
kaappi> (channel-receive ch)
;=> world
See also: channel-send,
make-channel
channel?¶
Syntax: (channel? obj)
Returns #t if obj is a channel, #f otherwise.
kaappi> (channel? (make-channel))
;=> #t
kaappi> (channel? (make-mutex))
;=> #f
kaappi> (channel? 'not-a-channel)
;=> #f
See also: make-channel