Overriding definitions from the R7RS base library

62 views
Skip to first unread message

A C

unread,
Jan 2, 2022, 10:27:46 AM1/2/22
to chibi-scheme
Hello,

I'm sorry that this question is more about the R7RS standard [1] than Chibi, but Chibi is the most R7RS-conformant Scheme implementation I could find and I am a bit confused by its behavior, so here it goes.

I was wondering whether R7RS allows overriding identifiers like "lambda", "+" etc. from the base library. There is this sentence at the end of 5.2 (page 25) which makes me think that it should not be possible (and this SO thread [2] seems to confirm my interpretation):

"In a program or library declaration, it is an error to import the same identifier more than once with different bindings, or to redefine or mutate an imported binding with a definition or with set!, or to refer to an identifier before it is imported."

However, here is a program that should result in an error in that interpretation, but prints "0" when run with the current version of Chibi (6615a746096274e0f6cdf27912563599ed613c49):

(import (scheme base) (scheme write))
(set! + 0)
(display +)

Am I misinterpreting the standard or is Chibi deviating from the standard here?

Thanks,

A C

John Cowan

unread,
Jan 2, 2022, 1:20:27 PM1/2/22
to chibi-...@googlegroups.com
On Sun, Jan 2, 2022 at 10:27 AM A C <aed...@gmail.com> wrote:

I was wondering whether R7RS allows overriding identifiers like "lambda", "+" etc. from the base library. There is this sentence at the end of 5.2 (page 25) which makes me think that it should not be possible (and this SO thread [2] seems to confirm my interpretation):

"In a program or library declaration, it is an error to import the same identifier more than once with different bindings, or to redefine or mutate an imported binding with a definition or with set!, or to refer to an identifier before it is imported."

Chibi's behavior, while perhaps surprising, is actually conformant.  The key to the situation is the phrase "is an error", which in the world of Scheme standardization specifies a situation that is not defined by the standard.  Implementations, therefore, can do what they like, and portable code cannot rely on any particular behavior.  In particular:

Chibi silently performs the assignment;
Chicken prints a warning and performs the assignment;
Larceny silently ignores the assignment;
Gauche prints a warning and ignores the assignment.

Other conforming behaviors are also conceivable, such as crashing the program.  The reason for allowing this flexibility is to permit implementations to trade off between greater safety and greater efficiency.

In cases where an implementation must signal an error, the phrase "an error is signaled" is used.

It's worth pointing out that it is not an error to rebind an imported identifier, so that (let ((+ 0)) +) will evaluate to 0 in all Schemes, as will even odder-looking things like (let ((lambda +)) (lambda 2 -2)).

A C

unread,
Jan 2, 2022, 2:01:51 PM1/2/22
to chibi-scheme
On Sunday, January 2, 2022 at 7:20:27 PM UTC+1 John Cowan wrote:
Chibi's behavior, while perhaps surprising, is actually conformant.  The key to the situation is the phrase "is an error", which in the world of Scheme standardization specifies a situation that is not defined by the standard.  Implementations, therefore, can do what they like, and portable code cannot rely on any particular behavior.  In particular:

Chibi silently performs the assignment;
Chicken prints a warning and performs the assignment;
Larceny silently ignores the assignment;
Gauche prints a warning and ignores the assignment.

Other conforming behaviors are also conceivable, such as crashing the program.  The reason for allowing this flexibility is to permit implementations to trade off between greater safety and greater efficiency.

In cases where an implementation must signal an error, the phrase "an error is signaled" is used.

Thanks for the clarification! (Though I must admit that it's rather easy to mix up "is an error" and "an error is signaled", I need to be more careful when reading the report.)
 
It's worth pointing out that it is not an error to rebind an imported identifier, so that (let ((+ 0)) +) will evaluate to 0 in all Schemes, as will even odder-looking things like (let ((lambda +)) (lambda 2 -2)).

Actually, I have a confusion about this too. The sentence I cited makes redefining an imported binding with a definition an error, but I guess that only applies to _top level_ definitions (5.3.1)? The section on internal definitions (5.3.2) says that they are equivalent to letrec* expressions, so (let () (define + 0) 0) should evaluate to 0 with no errors?


Alex Shinn

unread,
Jan 2, 2022, 8:25:31 PM1/2/22
to chibi-...@googlegroups.com
Chibi allows set!ing imported globals to keep the implementation small
and simple - it uses the same code for programs/libraries as for the
REPL.

Yes, you can rebind any keyword locally with lambda, and usually with
an internal define (modulo the clause about making it impossible to
determine the boundary between internal definitions and expressions).

--
Alex
> --
> You received this message because you are subscribed to the Google Groups "chibi-scheme" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to chibi-scheme...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/chibi-scheme/187cdc21-f2aa-4c17-8612-ae9711e2179fn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages