Subject: [clisp-list] C function addresses

From: Knut Arild Erstad <[email-masked]>
Date: Thu, 27 Jul 2000 02:18:36 +0200

Hi,

I'm need to pass a callback function created with DEF-C-CALL-IN as an
argument to a C function (declared with DEF-C-CALL-OUT).  Something like
this:

;; Callback function
(def-c-call-in draw (:return-type nil))
(defun draw ()
  (...))

(defun some-function
  ...
  (glutDisplayFunc #'draw)
  ...)

This doesn't work, of course.  I don't want the lisp function #'DRAW, I
think what I need is the address of the C function draw.  How can I do
that?

For those interested: I am trying to make OpenGL bindings for clisp, more
specifically a port of the Allegro bindings found at
<URL:http://www.neci.nj.nec.com/homepages/mann/software-available.html>.
If OpenGL bindings for clisp already exists, please let me know.

-- 
Knut Arild Erstad

Vacuums are nothings.
We only mention them to let them know we know they're there.

---

From: Bruno Haible <[email-masked]>
Date: Thu, 27 Jul 2000 15:51:15 +0200 (CEST)

> (def-c-call-in draw (:return-type nil))

What does your def-c-call-out definition of glutDisplayFunc look like?

> think what I need is the address of the C function draw.

The FFI will convert the lisp function #'DRAW to the C function
address automatically, if you have the right declaration for glutDisplayFunc.

Bruno

---

From: Knut Arild Erstad <[email-masked]>
Date: Thu, 27 Jul 2000 18:30:24 +0200

> address automatically, if you have the right declaration for glutDisplayFunc.

Thanks, I got it to work now.  I was just using integers for pointers to
some kinds of C constructs (and still am for pointer to structs and
unions).  Once I added the proper c-function declaration, it worked.

I still have a small problem, though... is there some way to pass NULL/0
to a C function that expects a function?  For instance, glutIdleFunc(NULL)
can be used to "turn off" an animation callback, how can I do this in
lisp?

glutIdleFunc is defined as
(FFI:DEF-C-CALL-OUT GLUTIDLEFUNC (:NAME "glutIdleFunc")
  (:ARGUMENTS (#:G1132 (FFI:C-FUNCTION (:LANGUAGE :STDC) (:RETURN-TYPE NIL)))
  )
  (:RETURN-TYPE NIL)
)

Another somewhat unrelated problem I ran into: (* 0 1.1) returns 0, not
0.0.  Is this a bug?  It seems like strange behaviour to me...

-- 
Knut Arild Erstad

Vacuums are nothings.

---

From: Bruno Haible <[email-masked]>
Date: Thu, 27 Jul 2000 20:22:52 +0200 (CEST)

> can be used to "turn off" an animation callback, how can I do this in

It's a bug. A callback function will correctly convert NULL to NIL,
but in the other direction the conversion did not yet worked. I've
fixed it in the CVS now. Thanks for reporting it.

> 0.0.  Is this a bug?  It seems like strange behaviour to me...

The difference between 0 and 0.0 in Lisp sense is that 0.0 is an
approximate zero, possibly originated from the subtraction of two
different but very close numbers, whereas 0 is a precise zero - it is
always zero no matter how close you look.

If you take a precise zero and multiply it with a precise 0, you
always get a precise zero.

You can use COERCE to convert 0 to 0.0 if you want the latter (e.g. in
order to pass it as an argument to GL routines).

Bruno

---

From: Knut Arild Erstad <[email-masked]>
Date: Fri, 28 Jul 2000 02:07:28 +0200

> always zero no matter how close you look.
[...]

I understand the argument, but it still seemed unintuitive somehow, and
different from all other languages and Lisp versions I remember seeing, so
I looked it up both in Graham's ANSI Common Lisp book and the HyperSpec,
and there it is:

<URL:http://www.xanalys.com/software_tools/reference/HyperSpec/Body/
sec_12-1-4-4.html>

"The result of a numerical function is a float of the largest format among
 all the floating-point arguments to the function."

-- 
Knut Arild Erstad

Vacuums are nothings.

---

From: Bruno Haible <[email-masked]>
Date: Fri, 28 Jul 2000 15:30:45 +0200 (CEST)

Knut Arild Erstad writes:

> different from all other languages and Lisp versions I remember seeing

But it is closer to what a real computer algebra system does. Because
it is closer to the true mathematical result.

> <URL:http://www.xanalys.com/software_tools/reference/HyperSpec/Body/

This section applies only to float-float combinations. Look at section
12.1.4.1 and at section 12.1.3.3:

  "When the arguments to an irrational mathematical function are all
   rational and the true mathematical result is also (mathematically)
   rational, then unless otherwise noted an implementation is free to
   return either an accurate rational result or a single float
   approximation."

Bruno

---

From: Knut Arild Erstad <[email-masked]>
Date: Fri, 28 Jul 2000 16:20:47 +0200

> it is closer to the true mathematical result.

That I can agree with.  But it was certainly an unexpected result for me,
and I still think it is a violation of the standard...

>    return either an accurate rational result or a single float

"When the arguments to an irrational mathematic functions are *all*
 rational" ... this does not apply to (* 0 1.1).  From what I can see it
applies only to the functions listed in that section, and only if all
arguments are rational, so that (expt 0 1.1) must return 0.0, and
(log 1 2.0) must return 0.0, for instance.  clisp returns 0 in the second
case, BTW.

Section 12.1.4.1 says

"When rationals and floats are combined by a numerical function, *the
 rational is first converted to a float* of the same format. For functions
 such as + that take more than two arguments, it is permitted that *part*
 of the operation be carried out exactly using rationals and the rest be
 done using floating-point arithmetic."

It seems pretty clear to me: a numerical function with one or more float
arguments always returns a float (or in some cases a complex number with
float parts).  Am I missing something?

-- 
Knut Arild Erstad

Vacuums are nothings.