Gauche icon indicating copy to clipboard operation
Gauche copied to clipboard

cond-expand is not in R7RS initial environment

Open lassik opened this issue 5 years ago • 4 comments

Given a simple script test.scm as follows:

(cond-expand (r6rs (import (rnrs)))
             (r7rs (import (scheme base) (scheme write))))

(display "Hello world")
(newline)

This works:

$ gosh test.scm
Hello world

But this does not:

$ gosh -r 7 test.scm
*** ERROR: cannot find "rnrs" ...

The reason is that cond-expand is not defined in the initial R7RS environment. I know you like to keep a clean environment, but would you be willing to make an exception for cond-expand? It's very hard to write portable code without it.

lassik avatar Sep 15 '19 08:09 lassik

I agree that it's hard to write portable code, but such code as test.scm is already non-portable, so it doesn't make sense to try to run it in R7RS environment. If you need to rely on implementation's extention, you can use implementation-specific option anyway, e.g.:

gosh -r7 -e '(import (only (scheme base) cond-expand))' test.scm

So, what level of "portability" exactly you need?

If there'll be a convention among several implementations I don't mind to follow it. I think the easiest way is to agree an alias of srfi-0 (e.g. (import (srfi cond-expand))). Unfortunately we can't use the numeric name, for it differs between R6RS ((import (srfi :0))) and R7RS ((import (srfi 0))).

shirok avatar Sep 15 '19 09:09 shirok

I agree that it's hard to write portable code, but such code as test.scm is already non-portable, so it doesn't make sense to try to run it in R7RS environment. If you need to rely on implementation's extention, you can use implementation-specific option anyway

That's a good point. Perhaps it's overkill to use the -r 7 flag in this case. I haven't thought about the details at all. This sounds like either approach (with or without -r 7) will cause "surprises" eventually :)

So, what level of "portability" exactly you need?

As much as possible. Some simple but useful programs are almost completely portable between R6RS and R7RS already. The R6RS vs R7RS discrepancies are one of the main stumbling blocks for Scheme newbies.

If there'll be a convention among several implementations I don't mind to follow it. I think the easiest way is to agree an alias of srfi-0 (e.g. (import (srfi cond-expand))).

Good idea. However, cond-expand is so fundamental that would it make sense to try to get implementations to have it ready in the default environments even without any imports? Or are there several incompatible versions of cond-expand.

Unfortunately we can't use the numeric name, for it differs between R6RS ((import (srfi :0))) and R7RS ((import (srfi 0))).

True. That's unfortunate :|

lassik avatar Sep 15 '19 17:09 lassik

The story may not be so simple "just to use cond-expand".

R[67]RS Scheme actually consists of two different layers of languages. The "meta" language (import declarations and library declarations) sets up the semantics to evaluate the "base" language (commands and expressions). Without meta-language, the meaning of base-language program can't be determined.

However, we're talking about switching meta-languages, which is one layer above.

I suggested using srfi-0 above, but actually it doesn't necessarily work. Srfi-0 cond-expand is in the base-language level, so it can't switch imports, which are in meta-langauge level. R7RS has cond-expand in both levels (as library declaration, and as syntax). R6RS doesn't even have cond-expand in the language at all (you can use it in base-level after (import (srfi :0)).)

How to realize meta-language switching requires some design consideration, IMHO.

At this moment, I suppose the concensus is that R6RS and R7RS are different enough that you should have separete wrapper files for meta-language setup, which then include the common part written in base language. There are also lexical-level differences between 6 and 7, so you can't share anyway the code including such RnRS-dependent lexical sysntax.

Since we're talking outside of (or above) RnRS, we can establish a convention in such meta-meta-language level switching. I'm still ambivalent to conflate cond-expand for that purpose, simply because it's too easy to confuse different layers. But if we do, I think its worth a SRFI that formally extends the RnRS program structure:

<program> →
    <program declaration>+
   <command or definition>+

<program declaration> → <import declaration> 
   | (cond-expand <program cond-expand clause>+)

<program cond-expand clause> → 
   (<feature requriement> <program declaration>*)

shirok avatar Sep 15 '19 22:09 shirok

Good points all. I guess even in R7RS, the preferred use of cond-expand is inside define-library.

At this moment, I suppose the concensus is that R6RS and R7RS are different enough that you should have separete wrapper files for meta-language setup, which then include the common part written in base language. There are also lexical-level differences between 6 and 7, so you can't share anyway the code including such RnRS-dependent lexical sysntax.

That may be the most reasonable alternative.

Since we're talking outside of (or above) RnRS, we can establish a convention in such meta-meta-language level switching. I'm still ambivalent to conflate cond-expand for that purpose, simply because it's too easy to confuse different layers. But if we do, I think its worth a SRFI that formally extends the RnRS program structure:

I agree. It would be good to ask some people who really know the whole history of Scheme in and out. You raise many good points that I didn't consider, so I will refrain from pushing any agenda :)

lassik avatar Sep 17 '19 14:09 lassik