This came up in a discussion on a chibi issue (https://github.com/ashinn/chibi-scheme/issues/904), but is worth bringing up on the list.
R5RS had one use of the exclamation point, which was to indicate explicit mutation of a variable or storage location. SRFI 1 introduced the notion of linear update procedures, which effectively take ownership of their inputs. They may or may not mutate those inputs, making the original values unusable. This has both advantages and disadvantages. It encourages a functional style of programming while allowing implementations freedom to optimize. On the other hand, it makes it difficult to understand and predict memory usage. SRFI 1 chose to extend the use of the exclamation mark to linear update procedures. This was a debatable choice, since linear update procedures behave in many ways the opposite of the R5RS mutation procedures. The R5RS procedures have no return value, so they are always called as side-effecting and you later refer back to the input for the results. For linear update procedures you must always use the returned value and can never refer back to the input. You have to write in a functional style when using linear update and the implementation is encouraged not to mutate, yet everywhere you mark the procedures as using mutation. But it's probably too late to change this convention. SRFI 231 introduces yet a new notion, this time of "call/cc safety." The idea of this is that you can't detect internal state changes of a higher order function by using call/cc. Thus if you use map-in-order and the proc returns multiple times, each time it returns it will pick up where the continuation was captured, preserving any previous values and recomputing the rest. This property is not formally defined nor guaranteed by any existing standard procedure, but is not new, and is recognized as a generally useful property. The standard definition of `map` is actually a `map-in-order` with this property. On the other hand, neither the reference implementation nor most actual implementations of vector-map have this property. I'm not going to debate how important or useful call/cc safety it. In the context of arrays I will likely never want it due to the impractical overhead it incurs, but others might want it. What concerns me is the naming. SRFI 231 chose also to use the exclamation point for procedures _without_ this property. This introduces problems of 1. consistency, 2. naming conflicts, and 3. readability. 1. Consistency. By retroactive convention, for consistency, that would mean that R7RS `map` should in fact be named `map!`, although this is taken by the linear update version. Similarly we must adjust `for-each!`, `filter!` and so on for all existing higher-order procedures. 2. Naming Conflicts. As noted above, we have conflicts with linear-update variants using the same naming convention, as well as explicitly mutating variants like `vector-map!`. When working with very large arrays (which is trendy these days), conserving memory is of utmost importance, and explicit mutation can be desirable. However, the `array-map!` name I want that behaves like `vector-map!` would likely be interpreted in a very different way in the context of SRFI 231. 3. Readability. ! stands out as a nice visual indication of mutation (or in the case of linear update potential mutation), but in the case of non-call/cc-safe procedures it's there even when the programmer is not mutating anything. In particular, the inputs will never be mutated. With all of these different interpretations, I feel the exclamation point loses its meaning. A simple counter proposal would be to instead adopt a new suffix for the new type of procedure that has been introduced. Thus we could append call/cc safe procedures with /cc or ∞. -- Alex
