Hi,
It's the first time I come across CFFI after James Bielmann's initial questions on CFFI design in June 2005.
I had a short glance at the CLISP implementation and it immediately struck me that CFFI dislikes CLISP's consistent use of NIL for a NULL FFI pointer. Why?
I find using separate types for NULL and regular pointers extremely beneficial to programs. The "NIL is not a foreign-address" allows for cheap safety nets, i.e. my original AFFI (FFI for Amiga-CLISP, design in 1994/95) would error out when trying to mem-read from a NIL "pointer". The application won't crash. OTOH, I can understand that native-code compilers prefer homogenous types be used throughout the code (so i.e. type declarations look simpler, and maybe compilers like CMUCL's Python can avoid some boxing), but CLISP has been bytecode for over 13 years, which allows for different designs.
CLISP is very consistent about accepting and returning NIL for NULL pointers, so why does CFFI go to some length to reintroduce foreign pointers whose address is 0 instead of just using NIL?
BTW, IIRC my own UFFI-wrapper macros for CLISP, there was no problem at all with defining (deftype ffi-kind (or NULL FFI-ADDRSS FFI-VARIABLE FFI-FUNCTION)). So CLOS slots could have valid :type declarations.
FWIW, it's Bruno Haible whom whoever (James?) wrote a comment about beer in cffi-clisp.lisp owes a beer for exporting the interface to alignment of foreign types. It's been there since 1995.
Regards, Jörg Höhle.
On 2005-dec-09, at 13:55, Hoehle, Joerg-Cyril wrote:
I had a short glance at the CLISP implementation and it immediately struck me that CFFI dislikes CLISP's consistent use of NIL for a NULL FFI pointer. Why?
I'm not sure I dislike it. What I don't like is that CLISP doesn't offer a type that *doesn't* translate between NIL and a FFI pointer.
It's just that it's easy to come up with a type that does the NIL <-> NULL translation out of a raw pointer type.
(defctype :ptr :pointer)
(define-type-translator :ptr :to-c (type value) `(or ,type (null-pointer))
(define-type-translator :ptr :from-c (type value) (with-unique-names (pointer) `(let ((,pointer ,value)) (if (null-pointer-p ,pointer) nil ,pointer))))
IIRC, James deliberately doesn't want to translate between NIL and the NULL pointer because NIL shows up often in error situations. I suppose we could put this alternate type in CFFI for those who like it anyway?