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

Comments from ieee spec



 I recently grabbed a copy of the standard dated April 15 from
zurich.ai.mit.edu.  I am forwarding some comments that I think are
relevant for R4RS to this group too.

Since I am new to the scheme community, it would be presumptuous to
assume that I have understood the subtleties of all of the standard,
but there are some areas that were unclear to me or seemed to permit
contradictory interpretations, and I thought I would send out comments
on these areas.

I hope the scheme group will accept those comments that are helpful,
and I look forward to any feedback I may get on my misunderstandings.

DEFINE:

The semantics of DEFINE is historically problematic.  The change in
R3RS that eliminated the implicit LETREC in defines forces me to
generate code that checks to see if the procedure's variable has been
side effected by someone I call before I do the tail-recursive call.
If there were no other way to achieve side-effectability I would be
content with this, but it seems to me that there is an alternative
that does not require the compiler to pessimize the most-common-case:

First, I suggest that including (define <variable>) in R4RS, and
specifying that <variable> gets bound to an unspecified value
addresses the needs of both compilers and users.

If this change is made (I am sending this proposal to the
scheme-standard group too on the grounds that usage has effectively
standardized it), then the common case can be rewritten as:

	(define name	  =>  (begin (define name)
	   (lambda ...))	     (set! name
				       (letrec ((name (lambda ...)))
					  name)))

and the less-common case is still handled when needed by explicitly
writing the sequence

	(define name)
	(set! name (lambda ...))

Whatever is done, the semantics of what scope the lambda appears in
should be specified.

The only real problem I see with this is that it may imply a need to
extend BEGIN to handle things like

	(begin (define ...) (set! ...) (define ...))

WRITE:

Write should return #f on failure and #t on success, or it should be
an error to write a value to an external port that lacks an external
representation.

I advocate returning #t or #f, which would permit me to build a
wrapper function to deal with failure rationally, and avoids the need
to define external ports.  Failing to distinguish external ports from
internal ports is a bad idea because it constrains an implementation
 from defining something analogous to a pipe.  Returning #t or #f lets
the program deal with write errors by attempting to tell someone.

This would also permit an implementation to extend write such that it
can write continuations, and thereby implement DUMP-HEAP.  Programs
could assume this facility, try it, and issue an appropriate
diagnostic if it doesn't work.

The standard shouldn't include DUMP-HEAP, but it shouldn't constrain
WRITE in a way that prohibits it either.

GENERAL:

1) Implementations should be encouraged somewhere to implement (WRITE
<continuation>).  A representation should be written that when read
with READ results in a thunk that is an equivalent function to the
written continuation.  The representation of continuations should be
implementation-defined.

Rationale:  We all acknowledge that this is pragmatically something
that we want, and there should be a standard interface.  Having write
return a value lets me assume the capability without causing problems
for implementations that don't support it.

2) I believe that the user-interface section should specify a
procedure (DUMP-WORLD "filename" <continuation>) that writes a
representation that can be executed in an implementation-dependent way
to arrive at the specified continuation.  The <continuation> argument
should be optional, and if left unspecified should default to the
continuation that DUMP-WORLD will return to.  DUMP-WORLD should return
#t if it succeeds or #f if it fails or the implementation doesn't
supply the functionality.

Rationale:  The whole community acknowledges that we want this, but
that it is implementation-dependent.  This proposal permits us to
specify the interface to it and construct our programs in a way that
deals gracefully with failure and doesn't impose it on
implmementations that don't or can't do it.

Why DUMP-WORLD and not DUMP-HEAP?  Unlike DUMP-HEAP, which is covered
by WRITE, DUMP-WORLD does something fundamentally
implementation-specific.