Scheme deliberately makes no distinctions between "special forms" and "macros".  The division in RnRS into "primitive syntax" and "derived syntax" is purely pedagogical.  There is nothing stopping an implementer from defining "if" in terms of "cond", or "lambda" in terms of "case-lambda".

On Sun, Nov 3, 2019 at 5:54 AM Lassi Kortela <> wrote:
>> My argument for that is just compatibility and uniformity. For example,
>> if an RnRS procedure is extended with keyword arguments, that can't be
>> done in a compatible way if the keyword procedure cannot act like a
>> normal procedure in every way.
> In R6RS, it can be done with identifier syntax.

Do you mean that e.g. `open-output-file` as an identifier would evaluate
to a genuine lambda, whereas `(open-output-file ...)` would be a macro
that expands to the keyword argument checking and finally a fast call to
a lambda?

The current text of 177 says that `keyword-lambda` and `keyword-call`
are "syntax". But I have nothing against them being special primitive
operators either. Is there particular language we can use in the SRFI to
say that? I think "special operator" is a Common Lisp term.

> As soon as we have syntax-case (or identifier syntax for
> er-macro-transformers) in R7RS, it can also be done there. (And the
> "Option 2" syntax already needs more than is in syntax-rules.)

That's true. You and John have convinced me to relax the requirement on
syntax-rules compatibility :)

> Maybe you could explain to me why it is so important that the
> implementation of SRFI 177 builds upon the native keyword argument
> system whenever one is present. This way we will end up only with the
> least common denominator. But for what purpose?

The motivation that spurred 177 was: Uf a Scheme library writer wants to
start using keyword arguments in their libraries today, how could we let
them do that? I probably didn't explain this motivation clearly enough
in the SRFI rationale; sorry about that.

Present compatibility sets quite different requirements than something
where we are only working toward future R7RS standardization. It means
we can't use any syntax or semantics that require upgrading existing
implementations or waiting for a new standard to be ratified. It has to
be implementable only using macros in existing implementations.

My primary interest with Scheme is portable code (between R6RS and R7RS,
and also between implementations that loosely implement those standards
but don't conform to every detail). From that perspective, doing keyword
args that are fully compatible with all existing native kw args, and the
only compromise is magic :foo and foo: symbols, is a huge win.

I understand that from a purity standpoint such hacks are suspect.
That's why I want to design 177 in such a way that it can be replaced
with a cleaner alternative later. But however it is done, 177 has to be
something that is usable today, without upgrading implementations,
simply by loading a library.

> What has to be done (and is being done:)) is to look at the various
> native systems to get the best ideas. Then all it has to be made sure
> that it isn't too hard to implement SRFI 177 on the most relevant
> Scheme systems.

This is very good as long as we have a "tower" of increasingly
sophisticated semantics, so that each level of the tower is a compatible
superset of all the lower levels.

177 is meant to be the lowest level of the tower: just unhygienic
keyword args, all of them optional, with #f default values. The simplest
useful thing.

But those semantics are a subset of the upper levels of the tower:
hygienic keyword args, default values, supplied-p parameters,
allow-other-keys, etc.

That means a library writer can pick the lowest level that fulfills
their requirements. Many libraries don't need anything fancier than
global keywords with #f defaults; they can use 177. If someone needs to
write wrappers that handle unfamiliar keywords, they can use the
hypothetical SRFI 178 with allow-other-keys. If someone needs something
even fancier, they can import that, etc.

The point is that at any time, the writer of a library picks the
most-widely-compatible thing that works. That ensures the library can be
enjoyed by as many Schemers as possible.

R7RS-small compatibility is very important from this standpoint, as is
continued R6RS compatibility. R7RS-large can more freely make a choice
about its approach to the keyword tower. But whatever choice it makes,
should have semantics that are compatible with the other alternatives.