Subject: [clisp-list] critique of default-foreign-language (was: tiny suggestion about foreign1.lisp (FFI))

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Mon Apr 15 00:19:15 2002

Hi,

Sam wrote on the 11th of March:
> done.  DEF-C-CALL-* are now deprecated and the default should be set
> using DEFAULT-FOREIGN-LANGUAGE (just like IN-PACKAGE).

For weeks now I've been thinking about how to express my dislikes
and what the core of the problem is. Here's an attempt at it:

I oppose the implementation of this patch.

While I like the idea of file-wide (or compilation unit wide)
defaults, the implemented solution fails to consider run-time behaviour.

o it only works in environments where a global default-foreign-language makes sense. However, in such an environment, the proposed solution is overkill.
o it doesn't handle dynamic function creation (at run-time) well.
o it may lead to the "it works for me [the programmer]!" disease.

Consider the following scenario:

Enters the programmer.
[The programmer is on UNIX. After some learnign by doing, s/he has
DEFAULT-FOREIGN-LANGUAGE globally set to :stdC (ANSI-C) because
that's the only sensible choice (C++ names not yet supported by
CLISP, doesn't know what K&R is).]

(defun regexp-exec (compiled-pattern text)
  ;; return exactly as many extra elements as there are () in the regexp.
  (let ((nsub (regexp-groups compiled-pattern)))
    (multiple-value-bind (errcode matches)
        (funcall (ensure-foreign-function #'regexec :type
          `(c-function
            :arguments ((preg c-pointer)
                        (nmatch size_t)
                        (results (c-ptr (c-array regmatch_t ,nsub)) :out :alloca))
            :return-type int))
         compiled-pattern
         (1+ nsub))
      (if (zerop errcode) matches))))
Programmer tests. Everything is fine.
Programmer exists.

Enters the luser.
[User is on M$-Windows.]
[M$-User's default-foreign-language is :STDCALL because Reini or Dan said most functions there are this way.]
(use-package "REGEXP")
(regexp-compile #)
(regexp-match #)
Crash
[After several hours lost searching, User complains on mailing list etc.]

Point taken in reliable and dependable software:
	Attempt to have the programmer *state the obvious*.

This is not necessarily against natural lazyness
(e.g. def-c-call-out vs. def-call-out).

I think a correct solution would be to close over the file's
declared foreign language. I don't know how to do that.

Special variables and dynamic binding are your ennemies here. That's
how Emacs-Lisp looses in front of Common Lisp and Scheme.

I believe any attempt at a solution in between no default and
default-by-closure is going to break and loose someplace.

My proposal:

o Do not deprecate DEF-C-CALL-OUT. That's what 99% or programmers
have been using 95% of time.
It consisely expresses the function's signature without
affecting arguments. Think about the subtle difference between:
(def-stdcall-call-out foo
   (:arguments ((callback (c-function (:arguments #)))))
   (:return-type int))
and
(default-foreign-language :stdcall)
(def-call-out bar
   (:arguments ((callback (c-function (:arguments #)))))
   (:return-type int))

o Make :stdc the *constant* and documented default when no :language is given.
I don't think this would break code. K&R C is history. IMHO this
should have been changed long ago at the same time that CLISP said:
#if !defined(ANSI)
  #error "An ANSI C or C++ compiler is required to compile CLISP!"

o Provide nice DEF-WIN32-CALL-OUT etc. macros to support people's natural lazyness, long for compactness and ease of reading.

(In other words, revert patch except for :C -> :stdc in parse-foreign-type.)

Think should prevent the situation where the programmer is used
not to indicate :language (which is completely acceptable) but where
the code works on some implicit assumption. Yet I still like the idea
of file-wide defaults.

Principles that I attempt to follow:
o Let programmers rely on documented and fixed semantics and behaviour.
o Think about referential transparency. Think about what functional programming has to say.
o Provide constant behaviour.
o Think about the difference between the compilation and the run-time
  environments (see appropriate section in Common Lisp).
o Don't make your program correct behaviour depend on some external and
  user configurable switch. (Some day, I may write an article about how
  broken all the *print- are). You'll shoot yourself in the foot in a
  couple of month or years.

Sorry for my reaction more than one month after the proposed patch.

Regards,
	Jorg Hohle.

---

From: Sam Steingold <[email-masked]>
Date: Tue Apr 16 07:31:28 2002

> * In message <[email-masked]>
> * On the subject of "[clisp-list] critique of default-foreign-language (was: tiny suggestion about foreign1.lisp (FFI))"
> * Sent on Mon, 15 Apr 2002 09:17:40 +0200
> * Honorable "Hoehle, Joerg-Cyril" <[email-masked]> writes:
>

your example does not use def-call-out!
the default-foreign-language is used not only in def-call-out, but also
in c-function.  do you want c-win32-function too?

if the calling convention (default-foreign-language) is so crucial,
let's make the :language argument required, even when
default-foreign-language is there.

having separate def-c-call-out, def-win32-call-out &c is "the scheme
way" (TM)  :-)

in your example, the problem could have been resolved by issuing a
default-foreign-language form in top-level

> Yet I still like the idea of file-wide defaults.

here you go! :-)

> o Don't make your program correct behaviour depend on some external
>   and user configurable switch. (Some day, I may write an article
>   about how broken all the *print- are). You'll shoot yourself in the
>   foot in a couple of month or years.

*print- is a nice gun.
yes, if you are not careful, you will hurt yourself.
This is a tradeoff between the US (2nd amendment) and Europe (only
police has guns.)
I am for the US approach -  freedom above all.

> Sorry for my reaction more than one month after the proposed patch.

we all suffer from slow responses.
why are you holding my patch in
<http://sourceforge.net/tracker/index.php?func=detail&aid=539701&group_id=1355&atid=101355>?

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
<http://www.palestine-central.com/> <http://www.mideasttruth.com/>
My other CAR is a CDR.