Does the Scheme standard still matter? (2015 February 16)

In the history of the Scheme language there are documents defining the “standard Scheme”: the report, the revised report, r4rs, r5rs, r6rs, r7rs. Vicare is an r6rs implementation. r6rs is hated. Some people say that it must die. I guess that: because some People That Matter hate it, other people just hate it because it is cool to do so; this is pretty normal human behaviour.

Philosophy of Scheme

Usually one refers to this quote, which is included in the introduction of the r6rs document:

Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.

How beautiful! How useful? As I see it: every general purpose language that tries to be useful becomes complex and, inevitably, features are piled up. But this philosophy has actually succeeded in defining concepts that are both instruments of thought and instruments of language implementation: closures, continuations, proper tail–call optimisation, the dynamic environment.

Every high–level construct in every Scheme implementation can be described by a composition of core language constructs and, indeed, some implementations actually transform the high–level language source code into core language forms that are compiled or interpreted. Some implementations define a core language that is actually pretty human–readable Scheme code.

Success! The philosophy is established and acknowledged. Let’s not sweat it anymore.

NOTE I have noticed only today that, while adapting the text of the r6rs documents for Vicare’s documentation, I cut out the paragraphs describing the report philosophy. I fixed this, they are included now.

Scheme implementations and r6rs

There are so many Scheme implementations that I have no will to list them, just get this (which does not list Vicare, he! he!) and this and this. Of the implementations supporting r6rs, listed on the report’s site:

Biwascheme

It is far from being a full implementation. There are no hygienic macros.

Chez Scheme

It has gone West.

Guile

It is not a full implementation; its web page claims to offer only partial support. In version 2.0.11 the expander has some incompatibilities (the same problem of Sagittarius described below and more5).

Ikarus

It has gone West. Vicare is a fork of Ikarus.

IronScheme

It is still alive. I do not know it. It appears full continuations are not implemented and will never be. This is a limitation from my point of view:

  • Continuations cannot be used to implement coroutines; some actually useful code that should work on a compliant r6rs implementation will not work on IronScheme.
  • Is the semantics of the standard guard syntax correct with respect to the dynamic environment? I do not know the answer.
Larceny

There has not been a release in years. I do not know what this means.

Mosh

There has not been a commit to the repository in years. In my humble opinion: it is to be considered gone West.

Racket

It implements r6rs through the executable plt-r6rs and (most likely) some other way of selecting the language. Racket’s people have rightfully gone their way, defining their own language, for their own purposes. I think it is fair to assume we should not rely on Racket’s implementation of r6rs, it is just legacy code for them.

Sagittarius

It is still alive. The expander has problems, with respect to r6rs compliance6.

Ypsilon

It has gone West.

Everything is all right: people move on. Concretely, for my purposes, the only r6rs implementation is Vicare.

Unanswered questions on the usefulness of r7rs

Every now and then I ask myself if it would be worth it to support r7rs under Vicare. One thing I am sure of is that: it would be more work; with the already long queue of things–to–do for Vicare: I have no will.

Both r5rs and r7rs define “small” languages; they have differences. I wonder what more r7rs truly has to offer over r5rs. When I skimmed over the r7rs report: nothing jumped into my eyes. Sure it has library forms and cond-expand is integrated in the language; these are very useful to write portable code. There is support for exceptions; good. So what?

The r7rs of my dreams is bigger than r6rs and backwards compatible. More syntaxes like receive (as defined by the srfi) and receive-and-return (as defined by Vicare); more utilities to write macros, like syntax/loc as defined by Racket; a universal interface for garbage collector finalisers; an unwind–protection mechanism that is as reliable as possible; non–blocking input/output ports; more standard libraries for coroutines, containers, networking, foreign–functions interface, file systems; an api for posix services.

The r7rs “small language” looks useless to me; is it only a convenient base on top of which to implement the future r7rs “big language”? So will I have to wait until the big language takes shape to build an opinion?

I am a mediocre programmer; nevertheless, r6rs allowed me to search, resurrect, adapt, document and test a fair amount of libraries in r6rs format. I treasured the work of other people. r7rs is backwards incompatible: this is like being hard tackled.

Scheme users communities

They are diverging. This is how I see it.

These communities form a non–community of Scheme users. Maybe I am not reading in the right places (or I am not stalking enough people to know what they are actually doing) but I do not perceive significant interaction. comp.lang.scheme is nearly a desert.

Is the Scheme standard still important?

If a standard does not aggregate the work of people, establishing a platform over which to build new stuff: it is irrelevant.


Footnotes

(5)

The following program must raise an “unbound identifier ciao” error according to r6rs, because the definition of ciao in the expansion of the doit use must be renamed to some hidden identifier. It correctly fails under Vicare, it just works under Guile.

#!r6rs
(import (rnrs))
(define-syntax doit
  (syntax-rules ()
    ((_)
     (define (ciao)
       (display 123)
       (newline)
       (flush-output-port (current-output-port))))))
(doit)
(ciao)

This breaks hygiene, because it is not possible to create hidden definitions in the output forms of macros without explicitly using with-syntax and generate-temporaries.

(6)

The following program is perfectly valid r6rs code and it prints 123\n under Vicare; under Sagittarius it raises an error.

#!r6rs
(import (rnrs))
(define (fun)
  (mac))
(fun)
(define-syntax mac
  (syntax-rules ()
    ((_)
     (begin
       (display 123)
       (newline)
       (flush-output-port (current-output-port))))))

Notice that the macro mac is defined after its use in the body of fun; this is no problem according to r6rs and it allows organising code without restrictions on the order of definitions. Very useful and, indeed, I use it all the time in my code, which does not run under Sagittarius.