Lassi Kortela <la...@lassi.io> writes: >>> That said, I think that in Scheme, standard is quite different from >>> portable – if something standard is implemented, it will be (mostly) >>> according >>> to the standard, so in this way it is ‘portable’, but that’s a big ‘if’. >>> For large Schemes (and small Schemes for which the RnRS or SRFI stuff is >>> implemented in a separate library that can easily be installed(*)), I don’t >>> expect much trouble, but for very minimalistic (or outdated Schemes, >>> but that holds for other languages as well) you might possibly be in >>> trouble. > > Indeed, Scheme doesn't have a clear separation between full-featured > RnRS implementations and subset implementation. Several people have > noted that this is confusing.
Maybe the r7rs-benchmark preludes and postludes could be a start for documentation of that? https://github.com/ecraven/r7rs-benchmarks/tree/master/src Example: Guile3-prelude.scm: https://github.com/ecraven/r7rs-benchmarks/blob/master/src/Guile3-prelude.scm (use-modules (ice-9 rdelim)) (define-syntax import (syntax-rules () ((import stuff ...) (begin) ;; do nothing ))) (define flush-output-port force-output) (define current-second current-time) (define (jiffies-per-second) internal-time-units-per-second) (define current-jiffy get-internal-real-time) (define exact inexact->exact) (define inexact exact->inexact) (define (square x) (* x x)) (define (write-string str out) (display str out)) ; sufficient for tail.scm (define (this-scheme-implementation-name) (string-append "guile3-" (version))) (read-enable 'r7rs-symbols) (print-enable 'r7rs-symbols) (use-modules (rnrs bytevectors) (rnrs base) (srfi srfi-9)) Could some of those be eligible to be merged into (guile-user) — the interactive module of the REPL? > There are subsets of e.g. C, ML, Haskell, and Perl, but these are > clearly indicated s such. > >> Is (import (srfi :N)) portable in practice? > > AFAIK: > > (import (srfi :N)) is portable across all R6RS implementations. > > (import (srfi N)) - without the colon - is portable across all R7RS > implementations. > > Mnemonic SRFI imports - e.g. (srfi 1 lists) - are currently not > available in any R7RS implementation. > > In R6RS land, at least some implementations support mnemonic SRFI > imports using the form (srfi :1 lists). I'm not sure how many. There > are discrepancies in the names (e.g. "lists") among some R6RS > implementations. > > It's really a mess that should be cleaned up. Any technical problems > have been overcome - it's entirely a social issue. It should be > pursued on the srfi-discuss mailing list. Thank you for the overview! Do you want to cross-post this part of your answer to the srfi-list? (I think I should be on there — but I still have to finish srfi-234 before committing to additional things) >> I switched from (use-modules ...) to (import ...) to get towards making >> my code easier to re-use on different Schemes, but I didn’t actually try >> using it on another Scheme implementation. > > Thank you for making the effort. > > The current crop of portable code has been written by very few > schemers. With a few extra people we will rapidly get more impressive > results. In my experience, the foundation provided by R6RS and R7RS is > excellent and the few known practical problems can be solved. > > https://github.com/arcfide/chez-srfi is a notable project in R6RS > portability. Despite its name, it is not limited to Chez Scheme. > > R7RS has an (include "...") mechanism which R6RS lacks. chez-srfi adds > a similar mechanism on top of the R6RS library system. The chez-srfi > mechanism is widely portable in practice. Does that work the same as Guile’s (include "...")? From the reference manual: -- Scheme Syntax: include file-name Open FILE-NAME, at expansion-time, and read the Scheme forms that it contains, splicing them into the location of the ‘include’, within a ‘begin’. If FILE-NAME is a relative path, it is searched for relative to the path that contains the file that the ‘include’ form appears in. If you are a C programmer, if ‘load’ in Scheme is like ‘dlopen’ in C, consider ‘include’ to be like the C preprocessor’s ‘#include’. When you use ‘include’, it is as if the contents of the included file were typed in instead of the ‘include’ form. Because the code is included at compile-time, it is available to the macroexpander. Syntax definitions in the included file are available to later code in the form in which the ‘include’ appears, without the need for ‘eval-when’. (*Note Eval When::.) For the same reason, compiling a form that uses ‘include’ results in one compilation unit, composed of multiple files. Loading the compiled file is one ‘stat’ operation for the compilation unit, instead of ‘2*N’ in the case of ‘load’ (once for each loaded source file, and once each corresponding compiled file, in the best case). Unlike ‘load’, ‘include’ also works within nested lexical contexts. It so happens that the optimizer works best within a lexical context, because all of the uses of bindings in a lexical context are visible, so composing files by including them within a ‘(let () ...)’ can sometimes lead to important speed improvements. On the other hand, ‘include’ does have all the disadvantages of early binding: once the code with the ‘include’ is compiled, no change to the included file is reflected in the future behavior of the including form. Also, the particular form of ‘include’, which requires an absolute path, or a path relative to the current directory at compile-time, is not very amenable to compiling the source in one place, but then installing the source to another place. For this reason, Guile provides another form, ‘include-from-path’, which looks for the source file to include within a load path. Best wishes, Arne -- Unpolitisch sein heißt politisch sein, ohne es zu merken. draketo.de
signature.asc
Description: PGP signature