Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Gambit-C's FFI and variadic functions

29 views
Skip to first unread message

galdor

unread,
Mar 12, 2008, 11:29:31 AM3/12/08
to
Hi,

I just began my scheme learning, and found this language really
interesting.
I use Gambit-C, and would like to use C libraries for various tasks;
currently, I'm writing a ncurses binding, and am stuck with a really
disturbing problem.

Variadic functions aren't supported by Gambit-C's FFI. So, how can I
call a function such as printw ?
It seems unlikely that it's not possible to make a ncurses binding
just because the variadic functions aren't supported (I hope so,
because in the other case, I'd have to find another Scheme
implementation whereas I really like Gambit-C).

Would you have an idea to sidestep this problem ?

Thank you.

Pascal J. Bourguignon

unread,
Mar 12, 2008, 12:10:51 PM3/12/08
to
galdor <kha...@gmail.com> writes:

The problem is that scheme is strongly, value typed, contrarily to C
which is weakly, variable typed. So it's hard (run-time costly and
unsafe) to provide a safe binding to C variadic functions. It is
better to do it in scheme.

What you could do, is to define with the FFI various typical function
signatures for the same C function.

eg. (printw-int an-int) --> printw("%d",an-int);
(printw-float a-float) --> printw("%f",a-float);
(printw-string a-string) --> printw("%s",a-string);

From these basic FFI, you could re-implement the variadic feature in scheme:

(define (printw fmt . args)
(let loop
((chunks (parse-printw-fmt fmt))
;; (parse-printw-fmt "abc %d def %s ghi %f klm")
;; --> ("abc " #<fmt-integer> " def " #<fmt-string>
;; " ghi " #<fmt-float> " klm")
(args args)
(if (null? chunks)
(if (null? args)
'nil
(error "Too many args"))
(loop (rest chunks)
(let ((item (first chunks))
(arg (first args)))
(cond
((string? item)
(printw-string item)
args)
((fmt-string? item)
(if (string? arg)
(printw-string arg)
(error "%s expects a string argument"))
(rest args))
((fmt-integer? item)
(if (integer? arg)
(printw-integer arg)
(error "%d expects an integer argument"))
(rest args))
((fmt-float? item)
(if (float? arg)
(printw-float arg)
(error "%f expects a float argument"))
(rest args))
...)))))))

Another way would be to ignore C formating, and just use some scheme
format module, and then use ncurse FFI only to write plain strings,
formated in scheme.

--
__Pascal Bourguignon__

galdor

unread,
Mar 12, 2008, 12:20:16 PM3/12/08
to
On Mar 12, 5:10 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

I found your last idea really interesting, since it adds the
possibility to extend the printf syntax, for example to print lists.
I'm gonna work on this, thank you a lot !

--
Nicolas Martyanoff

0 new messages