ChezScheme icon indicating copy to clipboard operation
ChezScheme copied to clipboard

"cond-expand" needed for easier porting other libs to chez

Open ChaosEternal opened this issue 9 years ago • 17 comments

with inclusion of "cond-expand" in Chez, will reduce the effort of porting 3rd party libraries to Chez. and seems it is standardized in r7rs

ChaosEternal avatar Aug 18 '16 04:08 ChaosEternal

Chez Scheme has a syntax-level cond expression called meta-cond that allows for conditional expansion of code. The test expression in meta-cond is just a general Scheme expression that can be evaluated at expansion time, for instance the example from the documentation uses (= (optimize-level) 3).

I could imagine providing this as functionality as cond-expand, but looking at the R7RS documentation, it looks like the test expression for cond-expand is much more restricted (though it sounds like it could be generalized on an implementation specific basis). However, Chez Scheme does not currently expose any "feature identifiers" or a way to determine what libraries are available. Would you need this latter functionality for it to be useful for you?

akeep avatar Aug 19 '16 03:08 akeep

I really want r7rs compatible cond-expand

ChaosEternal avatar Aug 19 '16 03:08 ChaosEternal

The library side of this is interesting, since we look for and load libraries based on filenames, but don't necessarily know if a library is available unless is imported, it is possible that cond-expand would have the side-effect of loading the library into the library manager.

akeep avatar Aug 19 '16 03:08 akeep

Since this issue is still open, here's a couple of things I stumbled across today that indicate the r7rs-small "specification" of cond-expand is a hot mess. It's not possible to have an implementation compatible with a spec that's nonsense. http://comp.lang.scheme.narkive.com/3N1291hB/r7rs-missing-library-export-in-the-base-library https://groups.google.com/forum/#!topic/scheme-reports-wg1/sMNF8k0h3So

jltaylor-us avatar Feb 10 '18 18:02 jltaylor-us

R7RS's cond-expand appearing in the body of libraries and programs is, in fact, not specified well.

However, R7RS's cond-expand appearing in library declarations is without these problems and has clear semantics. For practical purposes, it should be enough to implement (and use) only this form of cond-expand.

mnieper avatar Jul 14 '18 16:07 mnieper

R7RS's definition of cond-expand is somehow broken.

You can do something like

(cond-expand (r7rs) ...)

But according to R7RS cond-expand itself requires, that you first define:

(import (scheme base))

But that is already R7RS syntax.

For me it makes almost no sense to check in the second line, whether you can use R7RS syntax, after you have used R7RS syntax already in the first line.

Other Schemes allow cond-expand without requiring any import before. I have asked the Chibi author about this:

https://groups.google.com/g/chibi-scheme/c/mshVKn9qLhQ/m/9xl20xUIBQAJ

He thinks his idea about cond-expand is right. I think Gambit and Guile are right.

It seems to me that there is no agreement in the Scheme-world, what cond-expand should achieve.

ceving avatar Jan 14 '23 22:01 ceving

R7RS only defines about ... R7RS. Anything before the first import or define-library form is outside of the scope of R7RS; it is implementation's discretion to allow cond-expand there.

It would be certainly nice to have a portable way to switch different standards. Technically it should be a meta language rather than Scheme itself, because you can't assume any particular semantics of Scheme, though reusing cond-expand would be fine. A srfi, maybe?

shirok avatar Jan 16 '23 01:01 shirok

It would be certainly nice to have a portable way to switch different standards. Technically it should be a meta language rather than Scheme itself, because you can't assume any particular semantics of Scheme, though reusing cond-expand would be fine. A srfi, maybe?

No need to duplicate SRFI-0. That is the specification of the meta language.

The way R7RS has assimilated cond-expand was wrong, because cond-expand is meta. That is the whole idea about cond-expand. SRFI-0 It is the origin of all SRFIs, because SRFIs are not part of a particular RnRS. They exist for all Schemes. And therefor cond-expand must exist in all Schemes even if the particular Scheme does not apply to any RnRS. cond-expand must be an universal agreement a meta thing. It must be part of the boot loader of every Scheme and not part of any RnRS.

ceving avatar Jul 14 '23 09:07 ceving

@akeep​ena likhitaḥ:

The library side of this is interesting, since we look for and load libraries based on filenames, but don't necessarily know if a library is available unless is imported, it is possible that cond-expand would have the side-effect of loading the library into the library manager.

This is allowed by R7RS small. In fact, I think it’s probably the best way to implement it: the Right Thing imo is that library not only checks that a file claiming to be the library exists, but also that it can sensibly be imported. R7RS Large will, I think, probably suggest an implementation of (code-level) cond-expand in terms of meta-cond which implements (library ...) by trying to create an environment with environment with the library imported.

(It’s not 100% certain that meta-cond will make it into Large yet, but since it can be written as a simple syntax-rules macro anyway, it seems likely to me.)

@jltaylor-us​ena likhitaḥ:

Since this issue is still open, here's a couple of things I stumbled across today that indicate the r7rs-small "specification" of cond-expand is a hot mess. It's not possible to have an implementation compatible with a spec that's nonsense. http://comp.lang.scheme.narkive.com/3N1291hB/r7rs-missing-library-export-in-the-base-library https://groups.google.com/forum/#!topic/scheme-reports-wg1/sMNF8k0h3So

The specification is not nonsense. It is simply required that cond-expand in code use symbolic-identifier=? to find the and, or, not, library, and else keywords used in its test clauses. This is different to other constructs in Scheme code, but it is the same as the symbolic matching done by cond-expand in library declarations, where there is no such thing as literal-identifier=? because there are no definitions or bindings. It also matches the symbolic matching of feature names from the implementation’s features list, which could not really be done any other way. (Whether it was actually a good idea to copy this CL feature is another issue.)

To @ceving’s point (as far as I understand it):

To get a portable R7RS program, you cannot begin the program source file with cond-expand. The only thing allowed there is an import. If you need a portable way for a program to do stuff with cond-expand to decide which libraries to import, you can write your ‘program’ as a dumb entry-point like this:

(import (my-program))
(run-my-program)

then in the declaration of the my-program library you can use cond-expand like you want.

It’s possible that some Schemes allow cond-expand at the top of a program; I think they are wrong to do so, but that’s their choice. But if you write your program in this way, as @shirok says, it is not a program in the sense of R7RS.

dpk avatar Nov 13 '23 16:11 dpk

@dpk

It’s possible that some Schemes allow cond-expand at the top of a program; I think they are wrong to do so

Of course they are not wrong! At the time cond-expand has been invented (1999!) this was the normal case. Take a look at SRFI-0:

Control over the presence of individual features will vary over different Scheme systems. A given feature may be absent or provided by default in some Scheme systems and in others some mechanism (such as an "import" clause in the code or a program configuration file, a command line option, a dependency declaration in a module definition, etc.) will be required for the feature to be present in the system.

It is exactly mentioned that cond-expand is intended to check for the existence of an import clause. And now, 20 years later, you say they have been wrong, because they did not respect a standard defined 20 years later. That is just silly!

ceving avatar Nov 14 '23 22:11 ceving

@dpk

It’s possible that some Schemes allow cond-expand at the top of a program; I think they are wrong to do so

import did not exist at that time, either.

‘Programs’ of that age (which are not ‘top-level programs’ in the sense of either R6RS nor R7RS, and will thus also not run in Chez Scheme in this sense) can generally be run in R7RS as ‘REPL scripts’ (see the last paragraph of section 5.7 of the small language report, page 30 left column). Updating them to compliance with R7RS small is not such an arduous task, though.

dpk avatar Nov 15 '23 08:11 dpk

I agree with @ceving insofar that R7RS's cond-expand is limited compared to what SRFI 0 offers; it is different in character and is no substitute in a world where not all schemes are R7RS schemes.

@ceving says that cond-expand is/was/should be meta, to which I agree. In fact, it should be part of some build system and not of Scheme proper.

The specification is not nonsense. It is simply required that cond-expand in code use symbolic-identifier=? to find the and, or, not, library, and else keywords used in its test clauses. This is different to other constructs in Scheme code, but it is the same as the symbolic matching done by cond-expand in library declarations, where there is no such thing as literal-identifier=? because there are no definitions or bindings. It also matches the symbolic matching of feature names from the implementation’s features list, which could not really be done any other way. (Whether it was actually a good idea to copy this CL feature is another issue.)

This is not how R7RS describes it; from the description in R7RS it follows that free-identifier=? is to be used, which, however, won't lead to a helpful cond-expand form.

mnieper avatar Nov 15 '23 09:11 mnieper

This is not how R7RS describes it; from the description in R7RS it follows that free-identifier=? is to be used, which, however, won't lead to a helpful cond-expand form.

I don’t see how one can interpret R7RS small this way. E.g. none of the keywords in cond-expand are listed as auxiliary syntax keywords under the entry for the code version of cond-expand, unlike keywords in other syntax entries which are matched by free-identifier=?.

dpk avatar Nov 15 '23 09:11 dpk

This is not how R7RS describes it; from the description in R7RS it follows that free-identifier=? is to be used, which, however, won't lead to a helpful cond-expand form.

I don’t see how one can interpret R7RS small this way. E.g. none of the keywords in cond-expand are listed as auxiliary syntax keywords under the entry for the code version of cond-expand, unlike keywords in other syntax entries which are matched by free-identifier=?.

cond-expand is listed in section 4.2 "Derived expression types" dedicated to "hygienic" constructs. Consequently, a definition of cond-expand is given using syntax-rules in section 7.3, also named "Derived expression types". The syntax-rules matching is via free-identifier=?; matching by symbolic name cannot be done using syntax-rules.

I don't think the R7RS authors intended this behaviour, so it should be corrected in some erratum.

We should continue the discussion about R7RS outside the Chez Scheme issue tracker.

mnieper avatar Nov 15 '23 09:11 mnieper

I agree with @ceving insofar that R7RS's cond-expand is limited compared to what SRFI 0 offers; it is different in character and is no substitute in a world where not all schemes are R7RS schemes.

@ceving says that cond-expand is/was/should be meta, to which I agree. In fact, it should be part of some build system and not of Scheme proper.

Furthermore, what WG1 should or should not have done is now moot. Introducing meta-cond would have added phasing issues into a language which otherwise avoided them. cond-expand in code might not be an ideal solution, and you have to be careful about how you use it. Much the same can be said of many features in Scheme. But like those other features, it is useful in those situations where it is applicable.

dpk avatar Nov 15 '23 10:11 dpk

This is not how R7RS describes it; from the description in R7RS it follows that free-identifier=? is to be used, which, however, won't lead to a helpful cond-expand form.

I don’t see how one can interpret R7RS small this way. E.g. none of the keywords in cond-expand are listed as auxiliary syntax keywords under the entry for the code version of cond-expand, unlike keywords in other syntax entries which are matched by free-identifier=?.

cond-expand is listed in section 4.2 "Derived expression types" dedicated to "hygienic" constructs.

4.2 is introduced by saying: ‘The constructs in this section are hygienic, as discussed in section 4.3.’

The definition of hygiene in section 4.3 does not exclude the possibility of using symbolic-identifier=? to find keywords; syntax-rules happens not to offer this possibility, but neither of the two points of the R7RS small hygiene condition are broken by doing this.

Consequently, a definition of cond-expand is given using syntax-rules in section 7.3, also named "Derived expression types". The syntax-rules matching is via free-identifier=?; matching by symbolic name cannot be done using syntax-rules.

I don't think the R7RS authors intended this behaviour, so it should be corrected in some erratum.

I suggested deleting this sample implementation entirely by erratum but I believe it was considered too big a change to go in by erratum. The sample implementation is also deficient because it doesn’t know how to find out if a library exists, nor how to look up a feature identifier in (features). If there is any mistake in the inclusion of cond-expand in R7RS small, it was the decision to include this useless example of an implementation. But the example implementations are, thankfully, not considered normative.

I will ask John to consider adding a sentence noting that the keyword matching in the sample implementation is also wrong.

We should continue the discussion about R7RS outside the Chez Scheme issue tracker.

Since this is an issue about R7RS support in Chez Scheme, and you are spreading myths about R7RS apparently in order to discourage Chez Scheme from supporting the small language, I think it’s appropriate that I rebut this here.

dpk avatar Nov 15 '23 10:11 dpk

Since this is an issue about R7RS support in Chez Scheme, and you are spreading myths about R7RS apparently in order to discourage Chez Scheme from supporting the small language, I think it’s appropriate that I rebut this here.

Stop these personal accusations and ad hominem arguments, please.

The chair of WG1 has been using the word "hygienic" in the sense that identifiers are matched by binding and not by symbolic value. Strictly speaking, 4.3 does not say much about the phrase "the constructs in this section are hygienic" appearing in 4.2 because the hygiene conditions of 4.3 are for macros and their transformers and can only be applied when the transformer is known (because, otherwise, it is unclear which bindings and references are inserted).

Anyway, I suggested fixing cond-expand in R7RS and not leaving it in a state of flux, so this is hardly a way to "discourage supporting the small language".

(The only possible valid reasons for discouraging supporting (parts of) the small language I can think of are the following: 1. If adding a feature of R7RS would impair the existing Chez Scheme programming language or the compiler or harm the style of programs likely written. 2. If adding R7RS-small support would encourage people using R7RS-small instead of R6RS. The latter is certainly at least as political as it is technical.)

mnieper avatar Nov 15 '23 11:11 mnieper