Am 15.07.2017 um 02:55 schrieb William D Clinger: > Marc Nieper-Wißkirchen wrote: > >> As I said above, I wasn't aware of the incompatibility with the R6RS. In >> principle, coexisting could be possible because syntax-rules can behave >> differently when imported from different libraries, e.g. Larceny could >> make a difference between syntax-rules imported from (scheme base) or >> (srfi 149) or (rnrs syntax-case (6)). > That would create hard-to-find bugs when a program imports > syntax-rules from two different libraries, one of which > imports syntax-rules from (scheme base) and the other from > (rnrs base). By the R7RS, "in a program or library declaration, it is an error to import the same identifier more than once with different bindings", and "implementations are not required to detect or report the error, though they are encouraged to do so". This specific error is very easy to detect for an implementation and at no cost at runtime, so there seems to be no reason for an implementation not to report the error. Furthermore, do we expect many programs to import (scheme base) and (rnrs base) the same library? (This issue is not a particular new one, I think. A program combining R7RS-large and R6RS fragments will likewise have to cope with the fact that, say, string-hash from (scheme comparator) may not be the same procedure as string-hash from (rnrs hashtable (6)).) >> (That said, SRFI 149 says that a system supporting it should export the >> same syntax-rules from (scheme base) and (srfi 149). But this still >> leaves room for (rnrs syntax-case (6)).) > None of this has anything to do with syntax-case or with > (rnrs syntax-case). syntax-rules is exported by (rnrs base). I wrote (rnrs syntax-case (6)) because this was the library given at the beginning of this chapter: http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-13.html#node_sec_12.4. The argument doesn't change when syntax-rules is exported by (rnrs base). (Having never written a longer program in R6RS proper, I am confessing that I don't know by heart which of its libraries exports which identifier.) >>> From Saunders MacLane, Categories for the Working Mathematician, page 13: >>> >>> A functor is a morphism of categories. In detail, for categories >>> C and B a functor T: C -> B with domain C and codomain B consists >>> of two suitably related functions: The object function T, which >>> assigns to each object c of C an object Tc of B and the arrow >>> function (also written T) which assigns to each arrow f: c -> c' >>> of C an arrow Tf: Tc -> Tc' of B, in such a way that >>> >>> T(1_c) = 1_{Tc}, T(g∘f) = Tg ∘ Tf, (1) >>> >>> the latter whenever the composite g∘f is defined in C. >>> >>> Before I even try to guess what you mean by "functoriality", I'd want >>> to know what the categories C and B are in your use of that word. >> My category C is the category whose objects are patterns P and whose >> morphisms are macro transformers f: P -> Q. > That is not a category, because macro transformers do not map patterns > to patterns. (A morphism in a general category doesn't need to be a map at all.) I was slightly sloppy because I thought it would distract too much. Anyway, to be more precise (and, for simplicity, let's ignore literal identifiers and macro transformers with more than one syntax rule): Firstly, we define a quiver K. The set of vertices of K shall be the set of patterns P such that (_ . P) is a valid (top-level) pattern in a syntax rule, up to alpha conversion of pattern variables. Each triple (P, f, Q) that consists of two vertices P and Q of K and a macro transformer f that accepts syntax of the shape (_ . P) (i.e. syntax that is matchable by (_ . P)) and produces syntax of the shape Q shall define an edge of K going from P to Q. Now, let C be the category freely generated by that quiver. (In fact, there is a notion of "functor" that already makes sense on the level of quivers, and this notion would be sufficient here.) >> My functor T: C -> C is the >> endofunctor that maps a pattern P to the pattern (P ...) and that wants >> to map a macro transformer f: P -> Q to "the" macro transformer (f ...): >> (P ...) => (Q ...) that (intuitively) transform each instance of P in >> the list on the left into the corresponding instance of Q in the list on >> the right. > Because C, as you described it, is not a category, the T you described > is not a functor. See above for the clarification of C. To define T: C -> C, firstly, one defines T: K -> K, mapping each pattern P to (P ...) and each triple (P, f, Q) to ((P ...), (f ...), (Q ...)), where the macro transformer (f ...) is defined using the semantics of SRFI 149 and as I explained in my previous post. As C is freely generated by K, the endofunctor T: K -> K induces the endofunctor T: C -> C by the universal property of C. However, being that formal is probably not too helpful for most of the readers. From a programmers perspective: It is the semantics of SRFI 149 that allows one to take a macro transformer converting Xs into Ys and to derive in a simple manner a macro transformer that converts lists of Xs into lists of Ys. It is the gen-extract/gen-extract* example that demonstrates this. In the macro gen-extract, we have written a simple macro transformer concerned with a generator and list of variables. Using SRFI 149 semantics, we could lift this to a macro transformer concerned with a list of (generator and list of variables). (The relationship of gen-extract/gen-extract* is analogous to the relationship of receive/let*-values). >> SRFI 149's semantics has nothing to do with the relative positions of >> the pattern variables of different ranks. E.g. it would give the same >> result if the pattern was (foo2 (coordinate ...) ... (axis ...)). The >> way I read the R6RS, it either doesn't resolve the ambiguity or it >> intends to specify that the input forms of the lower-ranked pattern >> variables are repeated if necessary. > All six of the R6RS systems I tested give the same result with that > alternative pattern, which casts doubt on the idea that R6RS systems > are agreeing on every example we try just by accident. How many different macro expanders do these systems use at their heart? Regardless of the number of implementations, what R6RS most likely specifies (unfortunately, the text is rather terse, and SRFI 93 doesn't explain it better) is what I wrote in the previous post and which amounts to the fact that in case of extra ellipses in the template, the outermost ellipses replicate, while the inner ellipses iterate. SRFI 149, on the other hand, requires that the innermost ellipses replicate and that the outermost ellipses iterate. So, ignoring consistency between the various standards for the moment, the main question that remains is whether SRFI 149's semantics is more useful/is more intuitive/has more applications than R6RS's semantics, or whether their is a superior semantics to both, making foo2 and gen-extract* both possible at the same time. -- Marc