Email list hosting service & mailing list manager


SLIB and R7RS John Cowan 01 Jan 2015 07:19 UTC

The following information on SLIB and R7RS is being posted to the
SRFI 96 mailing list so as to have it at a single point.  Note that
“r7rs-small” and “WG1-Scheme” mean the same thing. The original
emails are linked at the end.

Note that things may have changed in SLIB since August 2011.

John Cowan:

SRFI 96, which is the foundation for SLIB, can't be implemented in its
entirety in R7RS-small.  In particular, SRFI 96 includes define-macro.

Aubrey Jaffer:

SLIB includes 108 macro-free modules and 27 which define or use
macros.

9 of the 27 use scanf, which should be refactored to be macro-free.

2 of the 27 use fluid-let.  SLIB developers have been rewriting
modules to avoid fluid-let; only two remain.

The SLIB promise module is superfluous in WG1-Scheme.

4 of the 27 define macro-systems (macro-by-example, syntax-case,
syntactic-closures, macros-that-work).  These would be eliminated in
favor of WG1-Scheme macros.

Seven implement SRFIs:

  SRFI 0: Feature-based conditional expansion construct
  SRFI 9: Defining Record Types
  SRFI 39: Parameter objects

These 3 are included in WG1-Scheme.

  SRFI 8: receive: Binding to multiple values
  SRFI 11: Syntax for receiving multiple values

Multiple values are addressed in WG1-Scheme.

  SRFI 2: AND-LET*: an AND with local bindings, a guarded LET* special form
  SRFI 61: A more general cond clause

No other SLIB modules uses these 2; they could be dropped without
harm.

That leaves only 4 syntax-defining packages: within-database, yasos,
trace, and break; and one package (collect) which uses yasos.

So 95% of SLIB would survive the transition to being macro-free.
SRFI-96 could be amended or superseded.

John Cowan:

Scanf is non-hygienic, so yes.

If the uses of fluid-let are essential, the syntax-rules definition in
SRFI 15 could be provided.  Alternatively, the uses might be replaceable
by parameters.

SRFI 11 is provided in R7RS-small, and SRFIs 2 and 8 are trivial
syntax-rules macros.

It would be good to know which of the SRFI-96 procedures (if any) are no longer
needed.

Aubrey Jaffer:

The procedural part of the SCANF module is SCANF-READ-LIST, which
takes a format-string and input-port or string as arguments and
returns a list of objects read.  Reading proceeds as far as the input
matches the format-string.

This would seem like a good application for multiple-value returns:
SCANF-READ would return the number of format directives matched
followed by the objects read.  But LET-VALUES, LET*-VALUES, and
(srfi-8) RECEIVE expect the number of bindings to match the number of
return values.  They can't be used if the number of return values is
not known in advance.

[Aaron Hsu noted that this is not true; LET-VALUES and LET*-VALUES
both accept improper lambda lists.]

So SCANF-READ must be used with CALL-WITH-VALUES; which is little help
with destructuring the list of values.  The VALUES constructs have
been disappointing because their use is not simpler or more powerful
than using LIST and APPLY.

CASE-LAMBDA can be used if the desired behavior changes radically with
different numbers of values; but often there is a lot of commonality
in the procedure.  A shared internal definition can't be called
because CASE-LAMBDA is the outer binding of the definition.  So either
code must be replicated in each clause or each clause must call an
external procedure with all the arguments.

[John Cowan noted that this is not true: LETREC can be used to bind
the name outside a CASE-LAMBDA.]

What would be helpful is something like:

  (BIND-VALUES
    <expression>
    ((<var1> [ <default-expression1> ])
     (<var2> [ <default-expression2> ])
     ...)
    <body>)

where <var1> gets bound to the first value returned by <expression>,
or to <default-expression1> if <expression> returned no values, or
signals an error if there is no <default-expression1>;
<var2> gets bound to the second value returned by <expression>, or to
<default-expression2> if <expression> returned fewer than 2 values, or
signals an error if there is no <default-expression2>, ...

The R7RS port of SLIB would drop the procedures:

  defmacro:eval
  defmacro:load
  macroexpand
  defmacro:expand*
  macro:expand

and would define:

  (define macro:eval slib:eval)
  (define macro:load slib:load)

URLs for email messages:

http://lists.scheme-reports.org/pipermail/scheme-reports/2011-August/001419.html
http://lists.scheme-reports.org/pipermail/scheme-reports/2011-August/001420.html
http://lists.scheme-reports.org/pipermail/scheme-reports/2011-August/001421.html
http://lists.scheme-reports.org/pipermail/scheme-reports/2011-August/001422.html
http://lists.scheme-reports.org/pipermail/scheme-reports/2011-August/001423.html

--
John Cowan          http://www.ccil.org/~cowan        xxxxxx@ccil.org
You escaped them by the will-death and the Way of the Black Wheel.
I could not.  --Great-Souled Sam