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.
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__
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