Subject: [clisp-list] Re: c-pointer: NULL == NIL polymorphism

From: Sam Steingold <[email-masked]>
Date: Mon Aug 4 07:53:10 2003

> * In message <[email-masked]>
> * On the subject of "Re: FFI crash: what am I missing?!"
> * Sent on Mon, 4 Aug 2003 13:00:33 +0200
> * Honorable "Hoehle, Joerg-Cyril" <[email-masked]> writes:
>
> Or allowing NIL for c-pointer (and return NIL for c-pointer as NULL!),
> as I said would be ok in last week's e-mail.

so, I take it that you think this is a good idea, right?
Unless Bruno objects, I will make NIL a valid value for c-pointer and
interpret it as a NULL pointer, and convert NULL to NIL on return.
the users will have to change their checks from

        (FFI:FOREIGN-ADDRESS-NULL return-value)

to

        (NULL return-value)

I will also remove the function FFI:FOREIGN-ADDRESS-NULL since it will
become useless.

objections?

<you can find the relevant discussion on clisp-devel; I move it to
clisp-list to get feedback from users on this proposed change>

-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
Oh Lord, give me the source code of the Universe and a good debugger!

---

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Tue Aug 5 08:40:03 2003

Sam wrote:

>Actually, IIUC, C does not know the difference between an array and a
>pointer (as a function argument), 
that's IMHO a common misconception.
>  so I don't really see why C-PTR and
>C-ARRAY do not accept NULL (=NIL) and thus make C-PTR-NULL and
>C-ARRAY-PTR necessary.
Think about c-ptr :out. Where's the argument?

The current FFI types  are carefully chosen so that SIZEOF is a total operation on them. SIZEOF obviously cannot work on variable sized arrays.

>Actually, it might be a good idea to go for consistency and make
>(unsigned-foreign-address 0) return NIL.
Are you boycotting my work or what? I wrote (in clisp-devel) why I consider *not* retuning NIL in that case consistent.
A #<foreign-address 00000000> is also consistent with the update foreign-pointer API I talked about some month ago. Adding NIL special cases is superfluous there. Let NIL live in the context of C-POINTER (and C-FUNCTION, C-ARRAY-PTR). There's still a place for #<foreign-address 0000000> when dealing with addresses.

I agree that users may not be too happy with the CLISP FFI because it hinders common patterns. That should not make them forget that it's one of the most expressive (or at least, precise) ones -- if that doesn't seem like a contradiction to you.

One key point to realize is: CLISP's FFI is able to work on as low a level as e.g. Allegro's, Lucid's, UFFI's etc. You just use C-POINTER almost everywhere and forget about :out, :in-out, , C-PTR etc. and all this declarative comfort stuff.
Just program as if you were using C. That's how I proceed every time when CLISP's high-level FFI doesn't match the interface requirements, e.g. with variable sized arrays (cf. today's sample code).

My (unwritten) DEF-LIB-VAR-CALL macro could help with variable-sized arrays in some situations, but it still fails to cover your "array size is indicated by another function" example.

But that's what I've experienced for every abstraction: it catches some situations/scenarios and fails to cover others. Lucky when it works.

Maybe instead of a macro, I should write a pattern/HOWTO instead. I've published instances of the macro expansion several times now, right here.

Actually, one may claim that it's the CLISP FFI's precision which hinders typical C usage. Because e.g. C declarations don't make a difference between C-PTR and C-PTR-NULL etc. and one has to read each individual manpage to know where NULL is allowed and where not.
E.g. char** provides for two pointer locations, both can be NULL, depending on the particular function. CLISP's FFI doesn't catch this well enough.

A conclusion could be: CLISP's FFI is not particularly well-suited for C style declarations. It's much better suited for COM/IDL kind of interface descriptions. Those are far more precise. Furthermore, interfaces across networks tend to be much more regular (:out is out, not "half in maybe out" as in the ** example).
Once again, I recommend reading
http://research.microsoft.com/Users/simonpj/Papers/papers.html
H/Direct: A Binary Foreign Language Interface for Haskell

I recommend learning about distributed programming, even if writing non-distributed applications. It's like when people say knowing about Lisp makes you a better C/Java/xyz programmer. Open you horizon, said some of the old greek (but that was heavily debated back then).

For one year and a half, I've tried to explain people how to use and put something (the FFI) to its full potential which I have not even designed nor written. I designed the AFFI.
My aproach since then has been to evolutionary bring the CLISP FFI close to the dynamics requirements I experienced using the AFFI and what I felt would be useful extensions (hence WITH-FOREIGN-OBJECT, dynamic library patch etc.), not to throw it away and replace the FFI by e.g. CMUCL's (whose syntax I prefer), revolutionarily.

Regards,
	Jorg Hohle.