This page is part of the web mail archives of SRFI 10 from before July 7th, 2015. The new archives for SRFI 10 contain all messages, not just those from before July 7th, 2015.
> Now consider > (cond-expand > ((and srfi-4 srfi-10 srfi-10-4) > (define sample-vector '#,(f32 1.0 2.0 3.0)))) > Note that mixing "cond-expand" and "#,(...)" as in this example is not > a good practice. That is because "#," operates at read-time and > cond-expand operates later, at macro-expansion time. So the > constructor for f32 will be executed regardless of the presence of > srfi-4, srfi-10, and srfi-10-4 (and if "#," is not supported by the > reader, you will get a reader error). You're absolutely right. I'm afraid I got carried away with the example and overlooked the timing problem. Sorry. I'd like to note however that according to R5RS conventions, a phrase "It is also an error if a reader-constructor associated with the tag cannot be located" does not necessarily mean that a read-time application error should crash the program and generate a core dump. An implementation may choose to treat a #,(foo arg...) form for an unknown tag foo as being equivalent to #f, the result of (if #f #f) or a form (error "read-time tag foo is unknown"). The latter two choices report an error lazily, shifting the burden of dealing with the error to another phase. A macro-expansion may however re-write the expression so that the erroneous form disappears. Therefore, there exists an implementation that can handle the example above as it stands. Alas, SRFI-10 reference implementation does not do that. > The "#," mechanism requires the user to understand yet another level > of compilation and the time when it is performed (and the model is > already not that simple if you consider forms like "(load ...)", > "(include ...)", and "(eval ...)", and the REPL). That's an excellent point. Let's indeed consider load and include forms. Provided that the following function is defined (define (read-all-as-a-begin-expr filename) (with-input-from-file filename (lambda () (cons 'begin (let loop ((datum (read))) (if (eof-object? datum) '() (cons datum (loop (read))))))))) and an 'include' reader-ctor is set up as (define-reader-ctor 'include read-all-as-a-begin-expr) The following form #,(include "foo.scm") appears to have the same semantics as (include "foo.scm") in Gambit. Furthermore, the load form can be defined as (define (load filename) (eval (read-all-as-a-begin-expr filename) (interaction-environment))) IMHO this illustrates rather well the difference and similarities between the include and load forms. As a matter of fact, this is almost literally how the include and load forms are implemented in Gambit, as a file gambc30/lib/_eval.scm reveals. Both forms rely on a ##read-all-as-a-begin-expr-from-port procedure, which reads from a port rather than a file.