Re: What are the long-term goals for R7RS in Chicken?
> On Jul 18, 2021, at 2:19 PM, Lassi Kortela wrote: > >> Note that include-files and loaded libraries are two different things, >> also in CHICKEN, libraries are usually compiled, so the .sld convention >> is only partially useful. > > The convention (observed at least by Chibi, Gambit, and Gauche) is that each > .sld file contains one define-library form. > > Gambit can compile something like hello.sld: > > (define-library (hello) > (import (scheme base)) > (begin (write-string "Hello world\n"))) > > into an object file hello.o1 via "gsc hello.sld". The gsi interpreter can > load either the original hello.sld or the compiled hello.o1. (I'm not sure > why it appends a running number to the ".o" suffix.) The same arrangement > would probably work for Chicken. The Gambit compiler produces a .oN file, a “dynamically loadable object file” that is normally a shared-object file, i.e. .so or .dll . The N is a stamp so the first time you compile foo.scm you get foo.o1, the second time foo.o2, etc. This is to avoid the restriction on some operating systems (namely Windows) that a given shared-object file can’t be loaded more than once even if the content has changed. Using a fixed file name would prevent calling (compile-file “foo.scm”) + (load “foo”) repeatedly from the REPL. Marc
Re: What are the long-term goals for R7RS in Chicken?
But I"d like to stress the fact that run-time and compile-time file locations may differ, also things like dynamic loading vs static linking come into play. In the end this is a build issue, not necessarily a question of run-time semantics. Sorry, I was being ambiguous. The natural strategy when dealing with R7RS is to compile each .sld file [i.e. each (define-library ...) form] into one .o or .so file, traversing any (include "...") files at compile time, not at runtime, so that the code in the included files becomes part of the object code corresponding to the .sld file. So you'd check foo.sld into git, and compile it and its dependencies into foo.so for dynamic linking, or into foo.o for static linking. Actually, the physical locations of code are secondary, as long as libraries are found, resolved and evaluated properly. Once again, I can not help but point towards "csm"[1], as a natural and convenient (yet, apparently sadly ignored), tool-based solution to this problem. I wasn't aware of the tool. Looks like good thinking went into it! For portable code, the main obstacle in practice is that a different wrapper file is required per each standard and/or implementation. For example, R6RS and R7RS typically require separate .sls and .sld files. (R6RS has many features that are not in R7RS-small, but a lot of useful code would be easily portable if it weren't for the different (library ...) vs (define-library ...) wrappers, as well as the implementation-specific module wrappers in Scheme implementations that predate R6RS. It would help a lot if one .sld file could cover all R7RS-capable implementations, even if (cond-expand ...)s have to be written inside the file. Reading csm's manpage, it seems to handle .sld files just as well as other kinds, but since it's not part of core Chicken, people tend to write eggs and other code in .scm files using (module ...) forms which complexifies the task of porting that code. Here's an example of a real library that's provided as both a Chicken egg and a R7RS (and R6RS) library in the same git repo: https://gitlab.com/weinholt/packrat. The implementation code that does the heavy lifting is shared among all three (packrat-r5rs.scm) but the library wrappers are all different (), and there's a little magic in packrat.egg and packrat.setup to enable things.
Re: What are the long-term goals for R7RS in Chicken?
> The convention (observed at least by Chibi, Gambit, and Gauche) is that > each .sld file contains one define-library form. > > Gambit can compile something like hello.sld: > > (define-library (hello) >(import (scheme base)) >(begin (write-string "Hello world\n"))) > > into an object file hello.o1 via "gsc hello.sld". The gsi interpreter > can load either the original hello.sld or the compiled hello.o1. (I'm > not sure why it appends a running number to the ".o" suffix.) The same > arrangement would probably work for Chicken. I think you can do the in Chicken as well, or I may misunderstand the implications ehre. > The code to implement simple libraries is often written directly into > the .sld file itself. Complex libraries tend to have the implementation > parcelled out into one or more separate .scm files, which are (include > "...") from the .sld file. Non-portable files may be included via > cond-expand. Looks easy enough to do. > > (include "...") must always specify the file name extension of the file > being included, though in practice that tends to always be ".scm". The > file foo/bar.sld files is imported via (import (foo bar)) and the import > never specifies the file name extension; ".sld" is implied, though > something else could be used as well; R6RS tends to use ".sls". But I"d like to stress the fact that run-time and compile-time file locations may differ, also things like dynamic loading vs static linking come into play. In the end this is a build issue, not necessarily a question of run-time semantics. Actually, the physical locations of code are secondary, as long as libraries are found, resolved and evaluated properly. Once again, I can not help but point towards "csm"[1], as a natural and convenient (yet, apparently sadly ignored), tool-based solution to this problem. cheers, felix [1] http://api.call-cc.org/5/doc/csm
Re: What are the long-term goals for R7RS in Chicken?
Note that include-files and loaded libraries are two different things, also in CHICKEN, libraries are usually compiled, so the .sld convention is only partially useful. The convention (observed at least by Chibi, Gambit, and Gauche) is that each .sld file contains one define-library form. Gambit can compile something like hello.sld: (define-library (hello) (import (scheme base)) (begin (write-string "Hello world\n"))) into an object file hello.o1 via "gsc hello.sld". The gsi interpreter can load either the original hello.sld or the compiled hello.o1. (I'm not sure why it appends a running number to the ".o" suffix.) The same arrangement would probably work for Chicken. The code to implement simple libraries is often written directly into the .sld file itself. Complex libraries tend to have the implementation parcelled out into one or more separate .scm files, which are (include "...") from the .sld file. Non-portable files may be included via cond-expand. (include "...") must always specify the file name extension of the file being included, though in practice that tends to always be ".scm". The file foo/bar.sld files is imported via (import (foo bar)) and the import never specifies the file name extension; ".sld" is implied, though something else could be used as well; R6RS tends to use ".sls". IMHO Gambit's R7RS support is simple, works well, and would probably be a reasonable model for Chicken.
Re: What are the long-term goals for R7RS in Chicken?
> If there are few substantial differences, it would be a boon to writing > portable code if the same syntax is eventually used as for standard R7RS > libraries, and the same filename conventions are supported as other R7RS > implementations (the .sld filename extension for an R7RS library is > becoming a de facto standard). You already support (include "...") and > (cond-expand ...) in a similar manner as R7RS. Note that include-files and loaded libraries are two different things, also in CHICKEN, libraries are usually compiled, so the .sld convention is only partially useful. felix
Re: What are the long-term goals for R7RS in Chicken?
On Sun, Jul 18, 2021 at 7:43 AM wrote: > Anybody for a "-r7rs" option that does the above? > I'd love to see that. Lassi: The fact that different Schemes have different conventions for where their library files are is actually a great convenience to me when developing SRFIs. All the actual code goes into files named *-impl.scm (or multiple names if there are multiple files). Then each library file or equivalent, which is where the differences are concentrated, is in an implementation-specific place. The library file for (foo bar) will be at: Chibi: foo/bar.sld Chicken: foo.bar.scm Guile: foo/bar.scm Ypsilon: foo/bar.sls, or foo/bar.ypsilon.sls if it is Ypsilon-specific And since each of these needs to be slightly different, that's a Good Thing.
Re: What are the long-term goals for R7RS in Chicken?
Currently you can switch to R7RS more by installing the egg and running csc with "-R R7RS -X R7RS", which is a mouthful, and could be abbreviated, that doesn't look to me like too much hassle. Anybody for a "-r7rs" option that does the above? +1 for an easy command line flag! Gauche and Sagittarius Scheme have an "-r" flag so you can run "sagittarius -r 6" or "gosh -r 7". Using one flag gives simple upward compatibility to "-r 8", "-r 9" in the future, and also non-RnRS standards or modes, should the need arise. Neither csc nor csi is yet using the "-r" flag for anything, so the uniformity would be nice. It also has nice symmetry with the upper case "-R" flag for extensions. A good question. I think the Chicken "native" language and module system is likely to be used more often than a R7RS mode, so I don't think there are any attempts to make Chicken "more R7RS". As you say, the differences are not that substantial. If there are few substantial differences, it would be a boon to writing portable code if the same syntax is eventually used as for standard R7RS libraries, and the same filename conventions are supported as other R7RS implementations (the .sld filename extension for an R7RS library is becoming a de facto standard). You already support (include "...") and (cond-expand ...) in a similar manner as R7RS. Here's how a typical module would look, before: ;;- (module lowdown (markdown->sxml markdown->sxml* markdown-sxml->html-sxml markdown->html markdown-html-conversion-rules*) (import scheme) (cond-expand (chicken-4 (import chicken) (use data-structures irregex srfi-1 clojurian-syntax comparse sxml-transforms lowdown-lolevel)) (chicken-5 (import (chicken base) (chicken irregex) (scheme) (srfi 1) (clojurian syntax) (comparse) (lowdown lolevel) (sxml-transforms ...code here...) ;;- And after: ;;- (define-library (lowdown) (export markdown->sxml markdown->sxml* markdown-sxml->html-sxml markdown->html markdown-html-conversion-rules*) (cond-expand (chicken-5 (import (scheme base) (chicken base) (chicken irregex) (srfi 1) (clojurian syntax) (comparse) (lowdown lolevel) (sxml-transforms (begin ...code here...)) ;;- Functors could use the existing syntax: (functor (squaring-functor (M (multiply))) (square) (import scheme M) (define (square x) (multiply x x))) or spell it `define-functor` for consistency. It should be possible to preserve the old (module ...) and (functor ...) syntax for backward compatibility so current modules keep working with no code changes.
Re: What are the long-term goals for R7RS in Chicken?
> Is there a consensus on how deeply to integrate R7RS into Chicken? It > seems mostly R7RS compliant as it stands. Are there any technical or > ideological blockers to basing core Chicken on R7RS-small in the future? > > The main point of divergence seems to be the native module system, which > offers a superset of the features of the R7RS library system. The common > features look more or less compatible, and this impression is reinforced > by the fact that you already have a useful r7rs egg. > A good question. I think the Chicken "native" language and module system is likely to be used more often than a R7RS mode, so I don't think there are any attempts to make Chicken "more R7RS". As you say, the differences are not that substantial. Currently you can switch to R7RS more by installing the egg and running csc with "-R R7RS -X R7RS", which is a mouthful, and could be abbreviated, that doesn't look to me like too much hassle. Anybody for a "-r7rs" option that does the above? felix
What are the long-term goals for R7RS in Chicken?
Is there a consensus on how deeply to integrate R7RS into Chicken? It seems mostly R7RS compliant as it stands. Are there any technical or ideological blockers to basing core Chicken on R7RS-small in the future? The main point of divergence seems to be the native module system, which offers a superset of the features of the R7RS library system. The common features look more or less compatible, and this impression is reinforced by the fact that you already have a useful r7rs egg.