[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: no constants please





    > From: Richard Kelsey <kelsey@xxxxxxx>

    >    Date: Sun, 4 Jan 2004 17:31:31 -0800 (PST)
    >    From: Tom Lord <lord@xxxxxxx>

    >    To reiterate -- I'm not convinced, now that I've noted you require
    >    GCPROtection of parameters in functions that may cause GC -- that
    >    Pika-conventions actually have more overhead.    

    > Right.  Efficient C code is the reason I prefer the proposed
    > SRFI's mechanisms to a JNI-style indirection.  Clarity of code
    > is why I prefer it to a Pika-style syntax.  Neither of these
    > decisions is defensible from first principles; it's a judgement
    > call.  As I said earlier, in some instances I would prefer to
    > use a JNI-style mechanism.


Ok then.  Neither of us like JNI-style conventions for this FFI and we
have similar reasons for reaching that conclusion.   So let's talk
about Pika.

It's one thing to brush aside some issue as an "author's judgment
call" if that issue has no semantic consequences.  I might argue that
"SCHEME_" is an unfortunate choice of prefix for the FFI but surely
that is a _purely_ syntactic issue and, basically, a petty complaint.

It's another thing to brush aside an issue as an "author's judgement
call" when the issue is how to make a trade-off between semantic
generality and syntactic realization.  You've put a pretty hefty list
of semantic issues on one side of the scale and your concerns about a
pretty short list of syntactic differences on the other.   I'm
genuinely surprised at the way your particular scale is tipping.

You say you don't like Pika because you think that the syntax required
by the Pika conventions damages code clarity.

As far as I can tell, the relevant syntactic differences between Pika
and the draft FFI are:

~ Pika doesn't use the C assignment operator.

  Instead of "x = y", one must write something like SCHEME_LSET (&x,
  &y).

  Instead of "x = foo ()", one must write "foo (&x)".


~ Pika requires address taking for parameters.

  Instead of "foo(x)", one must write "foo (&x)".


That's about it.  The differences in our GCPRO macros are, I hope you
agree, inconsequential (for example, while I prefer Pika's use of
structures for locals, I wouldn't consider an FFI using the draft's
style of GCPRO macros fatally flawed).  The issue of whether or not to
use an `instance' parameter is a semantic one, not a syntactic
difference.

I think the "problems" with Pika's C syntax can be summarized as:

	~ less visual distinctiveness to assignment
	~ more noise due to & characters

Anecdotally, I have found that two conventions help to moderate
the first of those problems:

	~ use upper-case for the variable-to-variable assignment
          operator, lower-case elsewhere.   This restores visual
          distinctiveness to one subset of assignment operations.

	~ given that Pika calls take an `instance' parameter, 
          output parameters go to the left of that, input parameters
          to the right.   This restores visual distinctiveness
          to the other subset of assignment operations.

And, of course, the "noise" of & characters actually provides useful
information to the C type checker -- their necessity forces the C
programmer to not make a certain class of usage errors.

You're right -- there's no accounting for taste, although I think we
can find some principled ways to look at the question:

One issue of principle is semantics.  The syntactic choice between
Pika and the draft has semantic consequences.  Pika is flat out less
restrictive of implementations regarding threads, async execution,
incremental collection, and the need for "(may GC)" declarations.
While the aesthetic questions may may be subjective, at least we
should agree that they better be darn strong aesthetic feelings to
justify the objective semantic compromises.

Another issue of principle is type checking.   The draft FFI gives
rise to many type-correct C expressions which are incorrect code:

     SCHEME_CONS (SCHEME_CONS (a, b), SCHEME_CONS (c, d))

whereas the type structure imposed by Pika conventions precludes such
errors.  It is partly a subjective call whether such errors are worth
trying to get the compiler to help prevent -- but it is also partly an
empirical call and a theoretical call from human factors
considerations.  Having had to fix buggy code like the above, written
by people who knew better, my subjective impression of the objective
(but unmeasured) empirical facts are that it is indeed worth getting
the compiler to help prevent such mistakes.  (The Pika conventions
permit the mistake of writing x = y where SCHEME_LSET (&x, &y) is
wanted -- but there too I think we can get a vanilla C compiler to
check for such errors should it become an issue.)

Another issue of principle is: you know where C++ is when you want it.
In other words: why not separate the problem of forming syntactic
abstractions for C-compatible code from the problem of getting the FFI
right in the first place?

Another issue of principle is that syntax clarity of a proposed
standard interface is not a subjective question: it's an empirical
one.  Experience with Pika-syntax is very limited at this point: three
people are writing code using it.  Still, two of those people did not
help to design it and picked it up just from the documentation and by
looking at existing code.  So far they seem to have picked it up
quickly and easily and have no problems using it.

Pika vs. the draft is, perhaps, a judgement call -- but I hope that
you either change how you are making it or can give better
justifications than "Well, I make that decision differently.  That's
my story and I'm sticking to it."

-t